diff --git a/design/FY2022/NFP-Space Heat Balance.md b/design/FY2022/NFP-Space Heat Balance.md new file mode 100644 index 00000000000..e39ce6e42e5 --- /dev/null +++ b/design/FY2022/NFP-Space Heat Balance.md @@ -0,0 +1,370 @@ +Subdivide Heat Balance by Space +================ + +**Michael J. Witte, GARD Analytics, Inc.** + + - Original April 22, 2022 + - Rev1 May 3, 2022 - Expand justification, make space heat balance calcs optional + - Rev2 June 29, 2022 - Plan Z, heat balances for zones only, add optional HVAC ZoneList to group Zones, make Zone Name optional for surfaces + - Rev3 July 8, 2022 - Revert Plan Z, stick with mostly original plan with optional space heat balance calcs + +## Table of Contents ## + +[Justification for New Feature](#justification-for-new-feature) + +[E-mail and Conference Call Conclusions](#e-mail-and-conference-call-conclusions) + +[Overiew](#overview) + +[Approach](#approach) + +[Testing/Validation/Data Sources](#testingvalidationdata-sources) + +[Input Description](#input-description) + +[Outputs Description](#outputs-description) + +[Engineering Reference](#engineering-reference) + +[Example File and Transition Changes](#example-file-and-transition-changes) + +[Design](#design) + +## Justification for New Feature ## + +Space was added as a new concept in v9.6. At the time, it was decided that the definition of Zone would not change: a thermal zone (HVAC zone) is composed of one or more rooms (spaces) controlled by a single thermostat or HVAC system control point such as a VAV terminal unit. This aligns with the most common understanding of a "zone" in HVAC design and energy modeling practice, including the OpenStudio data model. + +Currently, each EnergyPlus Zone contains one or more Spaces which are used for: + + * assigning and allocating internal gains + * specifying enclosure boundaries, + * reporting inputs grouped by space types, and + * reporting select output grouped by space types. + +The Zone air heat balance is currently lumped across all Spaces in the Zone. During the initial Space NFP discussions, additional capabilities were requested which would require an air heat balance for each Space: + + * Room-by-room sizing is commonly done to size individual room diffusers or equipment such as PTACs. Zone-level equipment may be sized to either the coincident or non-coincident peak across the rooms (Spaces). + + * Room-by-room HVAC simulation allows modeling the impact of thermostat placement in a specific room which often results in less-than-ideal temperature control for other rooms in the same Zone. For some applications, such as a unitary system with a single thermostat, this can be achieved by modeling each room as a separate Zone and using the "control zone" options. But this is not adequate for VAV systems or unitary systems with zoning controls. + +## E-mail and Conference Call Conclusions ## +Q1: What, if any, effect on runtime performance do we expect? + +A1: For this phase, the goal is to have a minimal impact on speed. Most of the calculations in the predictor-corrector are already looping over every surface, every internal gain, every HVAC supply node, etc. Looping over these groupings the space level and then aggregating results to the zone level shouldn't be costly. And radiant exchange is already at the enclosure-level, so that will not change. But just to be sure, the Space heat balance will be optional (and default to Zone-only). + +Q2: I still don't understand the need for this feature. If you want a finer resolution of heat balances, you can already make smaller zones, no? If you want room-by-room sizing, just make each room a separate zone. The current balance of zone and space allows you to aggregate things nicely to the higher level zone heat balance without incurring additional runtime associated with the additional heat balances for spaces that aren't expected to be thermally dissimilar. + +A2: The difference comes in the HVAC system sizing and controls. For unitary systems, one can make each room a separate zone, size each zone's airflow separately, and then use the current unitary system inputs for control zone and control flow fraction to model the system. But for other types of HVAC systems, such as VAV, there is no equivalent way to control the VAV damper (and reheat coil) based on a thermostat in one Space and split the airflow to diffusers in other Spaces. In the early discussions for the original Space implementation, one of the proposed approaches was to use Zones for the room-level model and add a new HVAC-Zone concept to group rooms for HVAC control. Ultimately, it was decided to keep Zone aligned with the concept of a group of Spaces (rooms) that are an HVAC control Zone. This is the next step along that path. Regarding performance, see Q1. + +**June 29, 2022 Technicalities Call** + +Plan Z was presented and discussed. Under Plan Z (heat balance only at the Zone level), if a user wanted room-by-room sizing data, then every room would need to be a Zone, and a new level of HVAC ZoneList would be used to group rooms (Zones) together for HVAC simulation and control. The question arose: "Why have Space then?" Further discussion revolved around the use case of room-by-room (Space-by-Space) sizing with Spaces grouped into large Zones for the HVAC simulation. + +One of the implmentation hurdles discussed was that the current heat balance method loops over `Zone.HTSurfaceFirst:HTSurfaceLast` in multiple places. Converting this to `Space.HTSurfaceFirst:HTSurfaceLast` requires sorting surfaces by Space instead of by Zone. This coding has already been done. + +## Overview ## + +The current implementation of Space includes the following key features: + +* Surfaces belong to both a zone and a space. +* Zones contain one or more spaces. +* Spaces have floor area (but not volume). +* Enclosures contain one or more spaces. +* Internal gains are allocated by space (input by zone or by space): + * People + * Lights + * Equipment (Electric, Gas, HotWater, Steam, Other, ITE:AirCooled) +* Outputs by Space include: + * Space Summary and Space Type Summary subtables of Input Verification and Results Summary + * Internal gain output variables (by object, space, and zone) + * Submeters by SpaceType (not by Space) + +The air heat balance is currently at the zone level only. While some components are already calculated and summed across spaces, the zone air heat balance, HVAC equipment simulation, and zone air temperature calculations are lumped for all spaces within the zone. This task will focus on refactoring the zone predictor/corrector functions to calculate air temperatures and heat balance components by Space as well as by Zone. + +## Approach ## + +1. The first step will be to ensure that all components of the heat balance are allocated by space. This will require changing some objects to allow specification by space or zone, similar to what is already done for people, lights, etc. + +2. The next step will be to calculate the Space air heat balance. This should be fairly straightforward, modifying existing calculation loops to sum components by Space instead of by Zone. + +3. Combining the Space results for the Zone will be more challenging. + + * Some Zone results are simply a sum of the Space results. + + * During sizing, all Spaces in the Zone will be controlled to the same thermostat temperature, so combining Spaces into Zones will be straightforward, and all surfaces will see the same air temperature. + + * During the HVAC simulation, for this task, the Space air masses will be lumped together for the Zone heat balance. This will force all Spaces in the Zone to the same air temperature. + + * Future work may add Space-level HVAC distribution and thermostat control options to allow calculation of independent Space air temperatures. + +Key aspects of the surface and air heat balances are listed below with italics indicating required changes. + +### Surface Heat Balance ### +* Surfaces are already assigned to a space and an enclosure. +* Solar and radiant internal gains to surfaces are simulated by enclosure. +* Radiant exchange between surfaces is simulated by enclosure. +* Surface convection to the air is currently to the zone air temperature (or suppply air temperature depending on the convection model). + * *Change to space air temperature.* + * *Surfaces which are assigned to an auto-generated space named "ZoneName-Remainder" may need special handling. If a Remainder space exists within a given zone, it may be necessary to lump the spaces in that zone together for the zone heat balance.* + +### Zone/Space Air Heat Balance ## + +* Surface convection to the air is currently to the zone air temperature. + * *Change to space air temperature.* +* Internal convective gains are already computed by space. +* Zone airflows for infiltration and mixing are currently by zone (ZoneInfiltration, ZoneMixing, ZoneCrossMixing). + * *Modify inputs to specify by zone or space (similar to internal gains, but allocated by volume or floor area depending on the input method).* +* Air volume is currently by zone. + * *Add input and calculations for Space volume. See [Issue #9362](https://github.com/NREL/EnergyPlus/issues/9362).* +* AirflowNetwork inputs and simulation will remain at the zone level. + * *Allocate the impact on the air heat balance by space. For this phase AFN zones may need to use a lumped air heat balance.* +* ZoneAirBalance:OutdoorAir will remain a zone-level input, and the same method will be applied to all spaces in the zone. +* ZoneRefrigerationDoorMixing is currently between two zones. + * *Modify inputs to specify by zone or space.* +* ZoneEarthtube will remain at the zone level, because it it thermostatically controlled. +* ZoneCoolTower:Shower is currently by zone. + * *Modify inputs to specify by zone or space.* +* ZoneThermalChimney models a zone to represent the chimney which then draws from one or more other zones. + * *Require that the thermal chimney zone has only one space. + * *Modify the inlet zone names to be zone or space.* + + +## Testing/Validation/Data Sources ## + +Zone-level results should stay the same. + +## Input Description ## +No new objects are proposed. Several existing objects will have changes. + +### HeatBalanceAlgorithm +* *Add a new field for Air Heat Balance Detail - Zone (default), ZoneAndSpace* + +### Space +* *Add new field for Volume.* +* *Add new field for Ceiling Height.* +* *Transition required.* + +### ZoneInfiltration:DesignFlowRate +* *Change field "Zone or ZoneList Name" to "Zone or ZoneList or Space or SpaceList Name."* + +### ZoneInfiltration:EffectiveLeakageArea and ZoneInfiltration:FlowCoefficient +* *Change field "Zone Name" to "Zone or Space Name."* + +### ZoneMixing and ZoneCrossMixing +* *Change field "Zone Name" to "Zone or Space Name."* + +* *Change field "Source Zone Name" to "Source Zone or Space Name."* + +### ZoneRefrigerationDoorMixing +* *Change field "Zone 1 Name" to "Zone or Space Name 1."* + +* *Change field "Zone 2 Name" to "Zone or Space Name 2."* + +### ZoneCoolTower:Shower +* *Change field "Zone Name" to "Zone or Space Name."* + +### ZoneThermalChimney +* *Change field "Zone N Name" to "Inlet Zone or Space Name N."* + +### ZoneControl:Thermostat:\* +* No change. Apply the same thermostat across all Spaces in the Zone. + +## Outputs Description ## + +Space equivalents will be added for the following zone output variables and meters (not sure about some of these, seems excessive): + +``` +Zone,Average,Zone Outdoor Air Drybulb Temperature [C] +Zone,Average,Zone Outdoor Air Wetbulb Temperature [C] +Zone,Average,Zone Outdoor Air Wind Speed [m/s] +Zone,Average,Zone Outdoor Air Wind Direction [deg] + +Zone,Average,Zone Mean Radiant Temperature [C] +Zone,Average,Zone Windows Total Transmitted Solar Radiation Rate [W] +Zone,Average,Zone Exterior Windows Total Transmitted Beam Solar Radiation Rate [W] +Zone,Average,Zone Interior Windows Total Transmitted Beam Solar Radiation Rate [W] +Zone,Average,Zone Exterior Windows Total Transmitted Diffuse Solar Radiation Rate [W] +Zone,Average,Zone Interior Windows Total Transmitted Diffuse Solar Radiation Rate [W] +Zone,Sum,Zone Windows Total Transmitted Solar Radiation Energy [J] +Zone,Sum,Zone Exterior Windows Total Transmitted Beam Solar Radiation Energy [J] +Zone,Sum,Zone Interior Windows Total Transmitted Beam Solar Radiation Energy [J] +Zone,Sum,Zone Exterior Windows Total Transmitted Diffuse Solar Radiation Energy [J] +Zone,Sum,Zone Interior Windows Total Transmitted Diffuse Solar Radiation Energy [J] +Zone,Average,Zone Windows Total Heat Gain Rate [W] +Zone,Average,Zone Windows Total Heat Loss Rate [W] +Zone,Sum,Zone Windows Total Heat Gain Energy [J] +Zone,Sum,Zone Windows Total Heat Loss Energy [J] + +Zone,Average,Zone Mean Air Temperature [C] +Zone,Average,Zone Operative Temperature [C] +Zone,Average,Zone Mean Air Dewpoint Temperature [C] +Zone,Average,Zone Mean Air Humidity Ratio [kgWater/kgDryAir] +HVAC,Average,Zone Air Heat Balance Internal Convective Heat Gain Rate [W] +HVAC,Average,Zone Air Heat Balance Surface Convection Rate [W] +HVAC,Average,Zone Air Heat Balance Interzone Air Transfer Rate [W] +HVAC,Average,Zone Air Heat Balance Outdoor Air Transfer Rate [W] +HVAC,Average,Zone Air Heat Balance System Air Transfer Rate [W] +HVAC,Average,Zone Air Heat Balance System Convective Heat Gain Rate [W] +HVAC,Average,Zone Air Heat Balance Air Energy Storage Rate [W] + +HVAC,Average,Zone Exfiltration Heat Transfer Rate [W] +HVAC,Average,Zone Exfiltration Sensible Heat Transfer Rate [W] +HVAC,Average,Zone Exfiltration Latent Heat Transfer Rate [W] +HVAC,Average,Zone Exhaust Air Heat Transfer Rate [W] +HVAC,Average,Zone Exhaust Air Sensible Heat Transfer Rate [W] +HVAC,Average,Zone Exhaust Air Latent Heat Transfer Rate [W] + +HVAC,Sum,Zone Infiltration Sensible Heat Loss Energy [J] +HVAC,Sum,Zone Infiltration Sensible Heat Gain Energy [J] +HVAC,Sum,Zone Infiltration Latent Heat Loss Energy [J] +HVAC,Sum,Zone Infiltration Latent Heat Gain Energy [J] +HVAC,Sum,Zone Infiltration Total Heat Loss Energy [J] +HVAC,Sum,Zone Infiltration Total Heat Gain Energy [J] +HVAC,Average,Zone Infiltration Current Density Volume Flow Rate [m3/s] +HVAC,Average,Zone Infiltration Standard Density Volume Flow Rate [m3/s] +HVAC,Sum,Zone Infiltration Current Density Volume [m3] +HVAC,Sum,Zone Infiltration Standard Density Volume [m3] +HVAC,Sum,Zone Infiltration Mass [kg] +HVAC,Average,Zone Infiltration Mass Flow Rate [kg/s] +HVAC,Average,Zone Infiltration Air Change Rate [ach] + +HVAC,Sum,Zone Air System Sensible Heating Energy [J] +HVAC,Sum,Zone Air System Sensible Cooling Energy [J] +HVAC,Average,Zone Air System Sensible Heating Rate [W] +HVAC,Average,Zone Air System Sensible Cooling Rate [W] +HVAC,Average,Zone Air Temperature [C] +HVAC,Average,Zone Thermostat Air Temperature [C] +HVAC,Average,Zone Air Humidity Ratio [] +HVAC,Average,Zone Air Relative Humidity [%] +HVAC,Average,Zone Predicted Sensible Load to Setpoint Heat Transfer Rate [W] +HVAC,Average,Zone Predicted Sensible Load to Heating Setpoint Heat Transfer Rate [W] +HVAC,Average,Zone Predicted Sensible Load to Cooling Setpoint Heat Transfer Rate [W] +HVAC,Average,Zone System Predicted Sensible Load to Setpoint Heat Transfer Rate [W] +HVAC,Average,Zone System Predicted Sensible Load to Heating Setpoint Heat Transfer Rate [W] +HVAC,Average,Zone System Predicted Sensible Load to Cooling Setpoint Heat Transfer Rate [W] +HVAC,Average,Zone Predicted Moisture Load Moisture Transfer Rate [kgWater/s] +HVAC,Average,Zone Predicted Moisture Load to Humidifying Setpoint Moisture Transfer Rate [kgWater/s] +HVAC,Average,Zone Predicted Moisture Load to Dehumidifying Setpoint Moisture Transfer Rate [kgWater/s] +HVAC,Average,Zone System Predicted Moisture Load Moisture Transfer Rate [kgWater/s] +HVAC,Average,Zone System Predicted Moisture Load to Humidifying Setpoint Moisture Transfer Rate [kgWater/s] +HVAC,Average,Zone System Predicted Moisture Load to Dehumidifying Setpoint Moisture Transfer Rate [kgWater/s] +Zone,Average,Zone Thermostat Control Type [] +HVAC,Average,Zone Thermostat Heating Setpoint Temperature [C] +HVAC,Average,Zone Thermostat Cooling Setpoint Temperature [C] +Zone,Average,Zone Adaptive Comfort Operative Temperature Set Point [C] +HVAC,Average,Zone Predicted Sensible Load Room Air Correction Factor [] + +HVAC,Sum,Zone Oscillating Temperatures Time [hr] +HVAC,Sum,Zone Oscillating Temperatures During Occupancy Time [hr] +HVAC,Sum,Zone Oscillating Temperatures in Deadband Time [hr] +HVAC,Sum,Facility Any Zone Oscillating Temperatures Time [hr] +HVAC,Sum,Facility Any Zone Oscillating Temperatures During Occupancy Time [hr] +HVAC,Sum,Facility Any Zone Oscillating Temperatures in Deadband Time [hr] +Zone,Sum,Zone Thermal Comfort ASHRAE 55 Simple Model Summer Clothes Not Comfortable Time [hr] +Zone,Sum,Zone Thermal Comfort ASHRAE 55 Simple Model Winter Clothes Not Comfortable Time [hr] +Zone,Sum,Zone Thermal Comfort ASHRAE 55 Simple Model Summer or Winter Clothes Not Comfortable Time [hr] + +Zone,Sum,Zone Heating Setpoint Not Met Time [hr] +Zone,Sum,Zone Heating Setpoint Not Met While Occupied Time [hr] +Zone,Sum,Zone Cooling Setpoint Not Met Time [hr] +Zone,Sum,Zone Cooling Setpoint Not Met While Occupied Time [hr] + +Output:Meter,Electricity:Zone:ZONE 1,hourly; !- [J] +Output:Meter:Cumulative,Electricity:Zone:ZONE 1,hourly; !- [J] +Output:Meter,InteriorLights:Electricity:Zone:ZONE 1,hourly; !- [J] +Output:Meter:Cumulative,InteriorLights:Electricity:Zone:ZONE 1,hourly; !- [J] +Output:Meter,GeneralLights:InteriorLights:Electricity:Zone:ZONE 1,hourly; !- [J] +Output:Meter:Cumulative,GeneralLights:InteriorLights:Electricity:Zone:ZONE 1,hourly; !- [J] +*and all types of end-uses and sub-end-uses* + +``` + +## Engineering Reference ## + +Summary paragraphs or sentences will be added to indicate that references to "Zone" throughout the heat balance documentation are applicable to "Space or Zone". + +## Example File and Transition Changes ## + +* The Space object will require transition to insert the new Ceiling Height and Volume fields. + +* No transition will be required for other idf inputs. + +* Field name changes will be required for epJSON inputs. + +* The existing example file 5ZoneAirCooledWithSpaces will demonstrate the new calculations. + +* A new example file with zone air flow objects by space will also be added. + +## Design ## + +* The main calculations happen in ZoneTempPredictorCorrector.cc. The functions here will be refactored to calculate values by space, then aggregate them by zone. + +* **OR** should the space and zone calculations be done in parallel? i.e. keep the existing zone calcs to maintain the same results, but then add space calcs on the side? + +* Any objects which are being modified to accept space or zone name will, of course, require changes to input processing, data structures and calulations. + +### ZoneTempPredictorCorrector.cc +`GetZoneAirSetPoints` +* No change - Thermostats and ZoneCapacitanceMultiplier:ResearchSpecial remain at the zone level. + +`InitZoneAirSetPoints` +* Many variables are allocated or dimensioned here per zone, zonelist, and zonegroup. Determine which ones need a space-level equivalent. +* Many zone output variables are set up here. Determine which ones need a space equivalent. +* Loop at line 2928 to check for matching `SurfTAirRef(SurfNum)` needs to be reworked per space(?). +* Some of the intitialization loops may need to be duplicated for spaces. + +`CalcZoneAirTempSetPoints` + +`CalcZoneSums` and `CalcZoneComponentLoadSums` +* Modify these functions to be by space, rename to `CalcSpaceSums` and `CalcSpaceComponentLoadSums`. +* OR add space sub-loops and data structures to store space values. This depends on how the functions which call `CalcZoneSums` and `CalcZoneComponentLoadSums` are refactored for spaces. + +``` +void CalcZoneSums(EnergyPlusData &state, + int const ZoneNum, // Zone number + Real64 &SumIntGain, // Zone sum of convective internal gains + Real64 &SumHA, // Zone sum of Hc*Area + Real64 &SumHATsurf, // Zone sum of Hc*Area*Tsurf + Real64 &SumHATref, // Zone sum of Hc*Area*Tref, for ceiling diffuser convection correlation + Real64 &SumMCp, // Zone sum of MassFlowRate*Cp + Real64 &SumMCpT, // Zone sum of MassFlowRate*Cp*T + Real64 &SumSysMCp, // Zone sum of air system MassFlowRate*Cp + Real64 &SumSysMCpT, // Zone sum of air system MassFlowRate*Cp*T + bool const CorrectorFlag) +``` + +* As part of this work it would be good to precalculate and store the full zone multipliers instead of recalculating them like this in many places throughout the code: +`ZoneMult = Zone(ZoneNum).Multiplier * Zone(ZoneNum).ListMultiplier;` + +`CalcZoneSensibleOutput` +* No change necessary inside the function,because all values are passed in as arguments. +* Calls to this function may need to be changed to pass in space values rather than zone values. + +`PredictSystemLoads` +* Break apart into multiple functions for + * Staged thermostat setpoint + * Setpoint revision for onoff thermostat + * Update zone/space temperatures + * Calculate zone/space heat balance terms + * Exact solution or Euler method - solve for zone/space air temp + * Calculate predicted loads + * Set OnOff Tstat status + +`CorrectZoneAirTemp` and `CorrectZoneHumRat` +* Break apart into multiple functions for + * Update zone/space temperatures (re-use same function from `PredictSystemLoads`?) + * Calculate zone/space heat balance terms (re-use same function from `PredictSystemLoads`?) + * Exact solution or Euler method - solve for zone/space air temp (re-use?) + * Bookkeeping + +`RevertZoneTimestepHistories` +* Refactor to handle zone or space + +`PushZoneTimestepHistories` +* Refactor to handle zone or space + +`PushSystemTimestepHistories` +* Refactor to handle zone or space + + + diff --git a/doc/input-output-reference/src/overview/group-simulation-parameters.tex b/doc/input-output-reference/src/overview/group-simulation-parameters.tex index 2dafddba217..2143569dc80 100644 --- a/doc/input-output-reference/src/overview/group-simulation-parameters.tex +++ b/doc/input-output-reference/src/overview/group-simulation-parameters.tex @@ -469,6 +469,12 @@ \subsubsection{Inputs}\label{inputs-8-023} Three choices are allowed to select which solution algorithm will be used. The \textbf{ThirdOrderBackwardDifference} selection is the default selection and uses the third order finite difference approximation to solve the zone air energy and moisture balance equations. The \textbf{AnalyticalSolution} selection uses the integration approach to solve the zone air energy and moisture balance equations. The \textbf{EulerMethod} selection uses the first order finite backward difference approximation to solve the zone air energy and moisture balance equations. +\paragraph{Field: Do Space Heat Balance for Sizing}\label{field-do-space-heat-balance-sizing} +If yes, space-level heat balance will be calculated and reported during sizing. If no, then only zone-level heat balance will be calculated. This field defaults to No. Note that space heat balance is not supported for \hyperref[inputs-hm]{HybridModel:Zone}, \hyperref[roomairmodeltype]{RoomAirModelType} other than Mixing, \hyperref[heatbalancealgorithm]{HeatBalanceAlgorithm} MoisturePenetrationDepthConductionTransferFunction and CombinedHeatAndMoistureFiniteElement. + +\paragraph{Field: Do Space Heat Balance for Simulation}\label{field-do-space-heat-balance-simulation} +If yes, space-level heat balance will be calculated and reported during the simulation. If no, then only zone-level heat balance will be calculated. This field defaults to No. + And, a default IDF example is shown below: \begin{lstlisting} diff --git a/doc/input-output-reference/src/overview/group-thermal-zone-description-geometry.tex b/doc/input-output-reference/src/overview/group-thermal-zone-description-geometry.tex index e0d7bf63664..4fb4b168db0 100644 --- a/doc/input-output-reference/src/overview/group-thermal-zone-description-geometry.tex +++ b/doc/input-output-reference/src/overview/group-thermal-zone-description-geometry.tex @@ -218,6 +218,54 @@ \subsubsection{Space Thermal Outputs Overview} Zone,Sum,Space Total Internal Total Heating Energy {[}J{]} \item Zone,Average,Space Total Internal Total Heating Rate {[}W{]} +\item + HVAC,Average,Space Air Temperature {[}C{]} +\item + Zone,Average,Space Mean Air Dewpoint Temperature {[}C{]} +\item + Zone,Average,Space Mean Radiant Temperature {[}C{]} +\item + Zone,Average,Space Operative Temperature {[}C{]} +\item + HVAC,Average,Space Air Heat Balance Internal Convective Heat Gain Rate {[}W{]} +\item + HVAC,Average,Space Air Heat Balance Surface Convection Rate {[}W{]} +\item + HVAC,Average,Space Air Heat Balance InterSpace Air Transfer Rate {[}W{]} +\item + HVAC,Average,Space Air Heat Balance Outdoor Air Transfer Rate {[}W{]} +\item + HVAC,Average,Space Air Heat Balance System Air Transfer Rate {[}W{]} +\item + HVAC,Average,Space Air Heat Balance System Convective Heat Gain Rate {[}W{]} +\item + HVAC,Average,Space Air Heat Balance Air Energy Storage Rate {[}W{]} +\item + HVAC,Average,Space Air Heat Balance Deviation Rate {[}W{]} +\item + HVAC,Sum,Space Air System Sensible Heating Energy {[}J{]} +\item + HVAC,Sum,Space Air System Sensible Cooling Energy {[}J{]} +\item + HVAC,Average,Space Air System Sensible Heating Rate {[}W{]} +\item + HVAC,Average,Space Air System Sensible Cooling Rate {[}W{]} +\item + HVAC,Average,Space Air Humidity Ratio{[}kgWater/kgDryAir{]} +\item + HVAC,Average,Space Air Relative Humidity{[}\%{]} +\item + HVAC,Sum,Space Air System Latent Heating Energy {[}J{]} +\item + HVAC,Sum,Space Air System Latent Cooling Energy {[}J{]} +\item + HVAC,Average,Space Air System Latent Heating Rate {[}W{]} +\item + HVAC,Average,Space Air System Latent Cooling Rate {[}W{]} +\item + HVAC,Average,Space Air System Sensible Heat Ratio {[}{]} +\item + HVAC,Average,Space Air Vapor Pressure Difference {[}Pa{]} \end{itemize} \subsubsection{Zone Thermal Outputs Overview}\label{zone-thermal-outputs} @@ -321,7 +369,7 @@ \subsubsection{Space and Zone Thermal Outputs Details} \paragraph{Zone Mean Air Temperature {[}C{]}}\label{zone-mean-air-temperature-c} -From the code definition, the zone mean air temperature is the average temperature of the air temperatures at the system timestep. Remember that the zone heat balance represents a ``well stirred'' model for a zone, therefore there is only one mean air temperature to represent the air temperature for the zone. +From the code definition, the zone mean air temperature is the average temperature of the air temperatures at the system timestep. Remember that the zone heat balance represents a ``well stirred'' model for a zone, therefore there is only one mean air temperature to represent the air temperature for the zone unless a non-mixing RoomAirModel is specified. \paragraph{Zone Air Temperature {[}C{]}}\label{zone-air-temperature-c} diff --git a/doc/input-output-reference/src/overview/group-zone-controls-thermostats.tex b/doc/input-output-reference/src/overview/group-zone-controls-thermostats.tex index 1c25b02dc80..8b9689d21f6 100644 --- a/doc/input-output-reference/src/overview/group-zone-controls-thermostats.tex +++ b/doc/input-output-reference/src/overview/group-zone-controls-thermostats.tex @@ -222,6 +222,18 @@ \subsubsection{Outputs}\label{outputs-042} HVAC,Average,Zone System Predicted Sensible Load to Heating Setpoint Heat Transfer Rate {[}W{]} \item HVAC,Average,Zone System Predicted Sensible Load to Cooling Setpoint Heat Transfer Rate {[}W{]} +\item + HVAC,Average,Space Predicted Sensible Load to Setpoint Heat Transfer Rate {[}W{]} +\item + HVAC,Average,Space Predicted Sensible Load to Heating Setpoint Heat Transfer Rate {[}W{]} +\item + HVAC,Average,Space Predicted Sensible Load to Cooling Setpoint Heat Transfer Rate {[}W{]} +\item + HVAC,Average,Space System Predicted Sensible Load to Setpoint Heat Transfer Rate {[}W{]} +\item + HVAC,Average,Space System Predicted Sensible Load to Heating Setpoint Heat Transfer Rate {[}W{]} +\item + HVAC,Average,Space System Predicted Sensible Load to Cooling Setpoint Heat Transfer Rate {[}W{]} \item Zone,Average,Zone Thermostat Control Type {[]} \item @@ -858,6 +870,18 @@ \subsubsection{Outputs}\label{outputs-2-027} HVAC,Average,Zone System Predicted Moisture Load to Humidifying Setpoint Moisture Transfer Rate {[}kgWater/s{]} \item HVAC,Average,Zone System Predicted Moisture Load to Dehumidifying Setpoint Moisture Transfer Rate {[}kgWater/s{]} +\item + HVAC,Average,Zone Predicted Moisture Load Moisture Transfer Rate {[}kgWater/s{]} +\item + HVAC,Average,Space Predicted Moisture Load to Humidifying Setpoint Moisture Transfer Rate {[}kgWater/s{]} +\item + HVAC,Average,Space Predicted Moisture Load to Dehumidifying Setpoint Moisture Transfer Rate {[}kgWater/s{]} +\item + HVAC,Average,Space System Predicted Moisture Load Moisture Transfer Rate {[}kgWater/s{]} +\item + HVAC,Average,Space System Predicted Moisture Load to Humidifying Setpoint Moisture Transfer Rate {[}kgWater/s{]} +\item + HVAC,Average,Space System Predicted Moisture Load to Dehumidifying Setpoint Moisture Transfer Rate {[}kgWater/s{]} \end{itemize} \paragraph{Zone Predicted Moisture Load Moisture Transfer Rate {[}kgWater/s{]}} diff --git a/doc/input-output-reference/src/overview/input-output-descriptions.tex b/doc/input-output-reference/src/overview/input-output-descriptions.tex index 0b8f98c9b13..def10172bae 100644 --- a/doc/input-output-reference/src/overview/input-output-descriptions.tex +++ b/doc/input-output-reference/src/overview/input-output-descriptions.tex @@ -107,6 +107,16 @@ \subsection{Output Descriptions}\label{output-descriptions} HVAC,Average,Zone Air Temperature {[}C{]} \item HVAC,Average,Zone Thermostat Air Temperature {[}C{]} +\item + HVAC,Sum,Space Air System Sensible Heating Energy {[}J{]} +\item + HVAC,Sum,Space Air System Sensible Cooling Energy {[}J{]} +\item + HVAC,Average,Space Air System Sensible Heating Rate {[}W{]} +\item + HVAC,Average,Space Air System Sensible Cooling Rate {[}W{]} +\item + HVAC,Average,Space Air Temperature {[}C{]} \end{itemize} Note that the \textbf{eplusout.mdd} file is similar, but meters are only available at the Zone timestep. diff --git a/idd/Energy+.idd.in b/idd/Energy+.idd.in index f1ee2015432..db79b098c14 100644 --- a/idd/Energy+.idd.in +++ b/idd/Energy+.idd.in @@ -771,16 +771,29 @@ HeatBalanceSettings:ConductionFiniteDifference, \maximum 0.01 ZoneAirHeatBalanceAlgorithm, - \memo Determines which algorithm will be used to solve the zone air heat balance. + \memo Controls the zone/space air heat balance. \unique-object \format singleLine - \min-fields 1 - A1 ; \field Algorithm + \min-fields 2 + A1 , \field Algorithm + \note Determines which algorithm will be used to solve the air heat balance. \type choice \key ThirdOrderBackwardDifference \key AnalyticalSolution \key EulerMethod \default ThirdOrderBackwardDifference + A2 , \field Do Space Heat Balance for Sizing + \note If yes, space heat balance will be calculated and reported during sizing. + \type choice + \key No + \key Yes + \default No + A3 ; \field Do Space Heat Balance for Simulation + \note If yes, space heat balance will be calculated and reported during simulation. + \type choice + \key No + \key Yes + \default No ZoneAirContaminantBalance, \memo Determines which contaminant concentration will be simulates. diff --git a/src/EnergyPlus/AirflowNetwork/src/Solver.cpp b/src/EnergyPlus/AirflowNetwork/src/Solver.cpp index c335766b84c..68add4a7a91 100644 --- a/src/EnergyPlus/AirflowNetwork/src/Solver.cpp +++ b/src/EnergyPlus/AirflowNetwork/src/Solver.cpp @@ -104,6 +104,7 @@ #include #include #include +#include namespace EnergyPlus { @@ -5423,8 +5424,8 @@ namespace AirflowNetwork { } for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) { - ANZT(i) = m_state.dataHeatBalFanSys->MAT(i); - ANZW(i) = m_state.dataHeatBalFanSys->ZoneAirHumRat(i); + ANZT(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).MAT; + ANZW(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).ZoneAirHumRat; if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) { ANCO(i) = m_state.dataContaminantBalance->ZoneAirCO2(i); } @@ -5452,16 +5453,16 @@ namespace AirflowNetwork { if (simulation_control.type != ControlType::NoMultizoneOrDistribution) { if (RollBackFlag) { for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) { - ANZT(i) = m_state.dataHeatBalFanSys->XMAT(i); - ANZW(i) = m_state.dataHeatBalFanSys->WZoneTimeMinus1(i); + ANZT(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).XMAT[0]; + ANZW(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).WPrevZoneTS[0]; if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) ANCO(i) = m_state.dataContaminantBalance->CO2ZoneTimeMinus1(i); if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) ANGC(i) = m_state.dataContaminantBalance->GCZoneTimeMinus1(i); } } else { for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) { - ANZT(i) = m_state.dataHeatBalFanSys->MAT(i); - ANZW(i) = m_state.dataHeatBalFanSys->ZoneAirHumRat(i); + ANZT(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).MAT; + ANZW(i) = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i).ZoneAirHumRat; if (m_state.dataContaminantBalance->Contaminant.CO2Simulation) ANCO(i) = m_state.dataContaminantBalance->ZoneAirCO2(i); if (m_state.dataContaminantBalance->Contaminant.GenericContamSimulation) ANGC(i) = m_state.dataContaminantBalance->ZoneAirGC(i); @@ -8724,7 +8725,8 @@ namespace AirflowNetwork { ZN2 = AirflowNetworkNodeData(M).EPlusZoneNum; // Find a linkage from a zone to outdoors if (ZN1 > 0 && ZN2 == 0) { - if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).SurfHasLinkedOutAirNode) { + auto &zn1HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN1); + if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).SurfLinkedOutAirNode > 0) { Tamb = m_state.dataSurface->SurfOutDryBulbTemp(MultizoneSurfaceData(i).SurfNum); CpAir = PsyCpAirFnW(Psychrometrics::PsyWFnTdbTwbPb(m_state, Tamb, @@ -8734,67 +8736,56 @@ namespace AirflowNetwork { Tamb = Zone(ZN1).OutDryBulbTemp; CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat); } - hg = Psychrometrics::PsyHgAirFnWTdb(m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1), m_state.dataHeatBalFanSys->MAT(ZN1)); + hg = Psychrometrics::PsyHgAirFnWTdb(zn1HB.ZoneAirHumRat, zn1HB.MAT); if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR || AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) { - if (Tamb > m_state.dataHeatBalFanSys->MAT(ZN1)) { - AirflowNetworkReportData(ZN1).MultiZoneInfiSenGainW += - (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - m_state.dataHeatBalFanSys->MAT(ZN1))); + if (Tamb > zn1HB.MAT) { + AirflowNetworkReportData(ZN1).MultiZoneInfiSenGainW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - zn1HB.MAT)); AirflowNetworkReportData(ZN1).MultiZoneInfiSenGainJ += - (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - m_state.dataHeatBalFanSys->MAT(ZN1))) * ReportingConstant; + (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - zn1HB.MAT)) * ReportingConstant; } else { - AirflowNetworkReportData(ZN1).MultiZoneInfiSenLossW += - (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN1) - Tamb)); + AirflowNetworkReportData(ZN1).MultiZoneInfiSenLossW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - Tamb)); AirflowNetworkReportData(ZN1).MultiZoneInfiSenLossJ += - (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN1) - Tamb)) * ReportingConstant; + (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - Tamb)) * ReportingConstant; } - if (m_state.dataEnvrn->OutHumRat > m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1)) { + if (m_state.dataEnvrn->OutHumRat > zn1HB.ZoneAirHumRat) { AirflowNetworkReportData(ZN1).MultiZoneInfiLatGainW += - (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1))) * - hg; + (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - zn1HB.ZoneAirHumRat)) * hg; AirflowNetworkReportData(ZN1).MultiZoneInfiLatGainJ += - (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1))) * - hg * ReportingConstant; + (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - zn1HB.ZoneAirHumRat)) * hg * ReportingConstant; } else { AirflowNetworkReportData(ZN1).MultiZoneInfiLatLossW += - (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1) - m_state.dataEnvrn->OutHumRat)) * - hg; + (AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * hg; AirflowNetworkReportData(ZN1).MultiZoneInfiLatLossJ += - (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1) - m_state.dataEnvrn->OutHumRat)) * - hg * ReportingConstant; + (AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * hg * ReportingConstant; } } else { - if (Tamb > m_state.dataHeatBalFanSys->MAT(ZN1)) { - AirflowNetworkReportData(ZN1).MultiZoneVentSenGainW += - (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - m_state.dataHeatBalFanSys->MAT(ZN1))); + if (Tamb > zn1HB.MAT) { + AirflowNetworkReportData(ZN1).MultiZoneVentSenGainW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - zn1HB.MAT)); AirflowNetworkReportData(ZN1).MultiZoneVentSenGainJ += - (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - m_state.dataHeatBalFanSys->MAT(ZN1))) * ReportingConstant; + (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (Tamb - zn1HB.MAT)) * ReportingConstant; } else { - AirflowNetworkReportData(ZN1).MultiZoneVentSenLossW += - (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN1) - Tamb)); + AirflowNetworkReportData(ZN1).MultiZoneVentSenLossW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - Tamb)); AirflowNetworkReportData(ZN1).MultiZoneVentSenLossJ += - (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN1) - Tamb)) * ReportingConstant; + (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - Tamb)) * ReportingConstant; } - if (m_state.dataEnvrn->OutHumRat > m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1)) { + if (m_state.dataEnvrn->OutHumRat > zn1HB.ZoneAirHumRat) { AirflowNetworkReportData(ZN1).MultiZoneVentLatGainW += - (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1))) * - hg; + (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - zn1HB.ZoneAirHumRat)) * hg; AirflowNetworkReportData(ZN1).MultiZoneVentLatGainJ += - (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1))) * - hg * ReportingConstant; + (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataEnvrn->OutHumRat - zn1HB.ZoneAirHumRat)) * hg * ReportingConstant; } else { AirflowNetworkReportData(ZN1).MultiZoneVentLatLossW += - (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1) - m_state.dataEnvrn->OutHumRat)) * - hg; + (AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * hg; AirflowNetworkReportData(ZN1).MultiZoneVentLatLossJ += - (AirflowNetworkLinkSimu(i).FLOW2 * (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1) - m_state.dataEnvrn->OutHumRat)) * - hg * ReportingConstant; + (AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * hg * ReportingConstant; } } } if (ZN1 == 0 && ZN2 > 0) { - if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).SurfHasLinkedOutAirNode) { + auto &zn2HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN2); + if (m_state.dataSurface->Surface(MultizoneSurfaceData(i).SurfNum).SurfLinkedOutAirNode > 0) { Tamb = m_state.dataSurface->SurfOutDryBulbTemp(MultizoneSurfaceData(i).SurfNum); CpAir = PsyCpAirFnW(Psychrometrics::PsyWFnTdbTwbPb(m_state, Tamb, @@ -8804,134 +8795,98 @@ namespace AirflowNetwork { Tamb = Zone(ZN2).OutDryBulbTemp; CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat); } - hg = Psychrometrics::PsyHgAirFnWTdb(m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2), m_state.dataHeatBalFanSys->MAT(ZN2)); + hg = Psychrometrics::PsyHgAirFnWTdb(zn2HB.ZoneAirHumRat, zn2HB.MAT); if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR || AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) { - if (Tamb > m_state.dataHeatBalFanSys->MAT(ZN2)) { - AirflowNetworkReportData(ZN2).MultiZoneInfiSenGainW += - (AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - m_state.dataHeatBalFanSys->MAT(ZN2))); + if (Tamb > zn2HB.MAT) { + AirflowNetworkReportData(ZN2).MultiZoneInfiSenGainW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - zn2HB.MAT)); AirflowNetworkReportData(ZN2).MultiZoneInfiSenGainJ += - (AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - m_state.dataHeatBalFanSys->MAT(ZN2))) * ReportingConstant; + (AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - zn2HB.MAT)) * ReportingConstant; } else { - AirflowNetworkReportData(ZN2).MultiZoneInfiSenLossW += - (AirflowNetworkLinkSimu(i).FLOW * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN2) - Tamb)); + AirflowNetworkReportData(ZN2).MultiZoneInfiSenLossW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - Tamb)); AirflowNetworkReportData(ZN2).MultiZoneInfiSenLossJ += - (AirflowNetworkLinkSimu(i).FLOW * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN2) - Tamb)) * ReportingConstant; + (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - Tamb)) * ReportingConstant; } - if (m_state.dataEnvrn->OutHumRat > m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2)) { + if (m_state.dataEnvrn->OutHumRat > zn2HB.ZoneAirHumRat) { AirflowNetworkReportData(ZN2).MultiZoneInfiLatGainW += - (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2))) * - hg; + (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - zn2HB.ZoneAirHumRat)) * hg; AirflowNetworkReportData(ZN2).MultiZoneInfiLatGainJ += - (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2))) * - hg * ReportingConstant; + (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - zn2HB.ZoneAirHumRat)) * hg * ReportingConstant; } else { AirflowNetworkReportData(ZN2).MultiZoneInfiLatLossW += - (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2) - m_state.dataEnvrn->OutHumRat)) * - hg; + (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * hg; AirflowNetworkReportData(ZN2).MultiZoneInfiLatLossJ += - (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2) - m_state.dataEnvrn->OutHumRat)) * - hg * ReportingConstant; + (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * hg * ReportingConstant; } } else { - if (Tamb > m_state.dataHeatBalFanSys->MAT(ZN2)) { - AirflowNetworkReportData(ZN2).MultiZoneVentSenGainW += - (AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - m_state.dataHeatBalFanSys->MAT(ZN2))); + if (Tamb > zn2HB.MAT) { + AirflowNetworkReportData(ZN2).MultiZoneVentSenGainW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - zn2HB.MAT)); AirflowNetworkReportData(ZN2).MultiZoneVentSenGainJ += - (AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - m_state.dataHeatBalFanSys->MAT(ZN2))) * ReportingConstant; + (AirflowNetworkLinkSimu(i).FLOW * CpAir * (Tamb - zn2HB.MAT)) * ReportingConstant; } else { - AirflowNetworkReportData(ZN2).MultiZoneVentSenLossW += - (AirflowNetworkLinkSimu(i).FLOW * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN2) - Tamb)); + AirflowNetworkReportData(ZN2).MultiZoneVentSenLossW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - Tamb)); AirflowNetworkReportData(ZN2).MultiZoneVentSenLossJ += - (AirflowNetworkLinkSimu(i).FLOW * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN2) - Tamb)) * ReportingConstant; + (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - Tamb)) * ReportingConstant; } - if (m_state.dataEnvrn->OutHumRat > m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2)) { + if (m_state.dataEnvrn->OutHumRat > zn2HB.ZoneAirHumRat) { AirflowNetworkReportData(ZN2).MultiZoneVentLatGainW += - (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2))) * - hg; + (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - zn2HB.ZoneAirHumRat)) * hg; AirflowNetworkReportData(ZN2).MultiZoneVentLatGainJ += - (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2))) * - hg * ReportingConstant; + (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataEnvrn->OutHumRat - zn2HB.ZoneAirHumRat)) * hg * ReportingConstant; } else { AirflowNetworkReportData(ZN2).MultiZoneVentLatLossW += - (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2) - m_state.dataEnvrn->OutHumRat)) * - hg; + (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * hg; AirflowNetworkReportData(ZN2).MultiZoneVentLatLossJ += - (AirflowNetworkLinkSimu(i).FLOW * (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2) - m_state.dataEnvrn->OutHumRat)) * - hg * ReportingConstant; + (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * hg * ReportingConstant; } } } if (ZN1 > 0 && ZN2 > 0) { - CpAir = PsyCpAirFnW((m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1) + m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2)) / 2.0); - hg = Psychrometrics::PsyHgAirFnWTdb( - (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1) + m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2)) / 2.0, - (m_state.dataHeatBalFanSys->MAT(ZN1) + m_state.dataHeatBalFanSys->MAT(ZN2)) / 2.0); - if (m_state.dataHeatBalFanSys->MAT(ZN1) > m_state.dataHeatBalFanSys->MAT(ZN2)) { - AirflowNetworkReportData(ZN2).MultiZoneMixSenGainW += - (AirflowNetworkLinkSimu(i).FLOW * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN1) - m_state.dataHeatBalFanSys->MAT(ZN2))); + auto &zn1HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN1); + auto &zn2HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN2); + CpAir = PsyCpAirFnW((zn1HB.ZoneAirHumRat + zn2HB.ZoneAirHumRat) / 2.0); + hg = Psychrometrics::PsyHgAirFnWTdb((zn1HB.ZoneAirHumRat + zn2HB.ZoneAirHumRat) / 2.0, (zn1HB.MAT + zn2HB.MAT) / 2.0); + if (zn1HB.MAT > zn2HB.MAT) { + AirflowNetworkReportData(ZN2).MultiZoneMixSenGainW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn1HB.MAT - zn2HB.MAT)); AirflowNetworkReportData(ZN2).MultiZoneMixSenGainJ += - (AirflowNetworkLinkSimu(i).FLOW * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN1) - m_state.dataHeatBalFanSys->MAT(ZN2))) * - ReportingConstant; + (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingConstant; } else { - AirflowNetworkReportData(ZN2).MultiZoneMixSenLossW += - (AirflowNetworkLinkSimu(i).FLOW * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN2) - m_state.dataHeatBalFanSys->MAT(ZN1))); + AirflowNetworkReportData(ZN2).MultiZoneMixSenLossW += (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - zn1HB.MAT)); AirflowNetworkReportData(ZN2).MultiZoneMixSenLossJ += - (AirflowNetworkLinkSimu(i).FLOW * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN2) - m_state.dataHeatBalFanSys->MAT(ZN1))) * - ReportingConstant; + (AirflowNetworkLinkSimu(i).FLOW * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingConstant; } - if (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1) > m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2)) { + if (zn1HB.ZoneAirHumRat > zn2HB.ZoneAirHumRat) { AirflowNetworkReportData(ZN2).MultiZoneMixLatGainW += - (AirflowNetworkLinkSimu(i).FLOW * - (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1) - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2))) * - hg; + (AirflowNetworkLinkSimu(i).FLOW * (zn1HB.ZoneAirHumRat - zn2HB.ZoneAirHumRat)) * hg; AirflowNetworkReportData(ZN2).MultiZoneMixLatGainJ += - (AirflowNetworkLinkSimu(i).FLOW * - (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1) - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2))) * - hg * ReportingConstant; + (AirflowNetworkLinkSimu(i).FLOW * (zn1HB.ZoneAirHumRat - zn2HB.ZoneAirHumRat)) * hg * ReportingConstant; } else { AirflowNetworkReportData(ZN2).MultiZoneMixLatLossW += - (AirflowNetworkLinkSimu(i).FLOW * - (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2) - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1))) * - hg; + (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.ZoneAirHumRat - zn1HB.ZoneAirHumRat)) * hg; AirflowNetworkReportData(ZN2).MultiZoneMixLatLossJ += - (AirflowNetworkLinkSimu(i).FLOW * - (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2) - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1))) * - hg * ReportingConstant; + (AirflowNetworkLinkSimu(i).FLOW * (zn2HB.ZoneAirHumRat - zn1HB.ZoneAirHumRat)) * hg * ReportingConstant; } - if (m_state.dataHeatBalFanSys->MAT(ZN2) > m_state.dataHeatBalFanSys->MAT(ZN1)) { - AirflowNetworkReportData(ZN1).MultiZoneMixSenGainW += - (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN2) - m_state.dataHeatBalFanSys->MAT(ZN1))); + if (zn2HB.MAT > zn1HB.MAT) { + AirflowNetworkReportData(ZN1).MultiZoneMixSenGainW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn2HB.MAT - zn1HB.MAT)); AirflowNetworkReportData(ZN1).MultiZoneMixSenGainJ += - (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN2) - m_state.dataHeatBalFanSys->MAT(ZN1))) * - ReportingConstant; + (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingConstant; } else { - AirflowNetworkReportData(ZN1).MultiZoneMixSenLossW += - (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN1) - m_state.dataHeatBalFanSys->MAT(ZN2))); + AirflowNetworkReportData(ZN1).MultiZoneMixSenLossW += (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - zn2HB.MAT)); AirflowNetworkReportData(ZN1).MultiZoneMixSenLossJ += - (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN1) - m_state.dataHeatBalFanSys->MAT(ZN2))) * - ReportingConstant; + (AirflowNetworkLinkSimu(i).FLOW2 * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingConstant; } - if (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2) > m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1)) { + if (zn2HB.ZoneAirHumRat > zn1HB.ZoneAirHumRat) { AirflowNetworkReportData(ZN1).MultiZoneMixLatGainW += - (AirflowNetworkLinkSimu(i).FLOW2 * - (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2) - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1))) * - hg; + (AirflowNetworkLinkSimu(i).FLOW2 * (zn2HB.ZoneAirHumRat - zn1HB.ZoneAirHumRat)) * hg; AirflowNetworkReportData(ZN1).MultiZoneMixLatGainJ += - (AirflowNetworkLinkSimu(i).FLOW2 * - (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2) - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1))) * - hg * ReportingConstant; + (AirflowNetworkLinkSimu(i).FLOW2 * (zn2HB.ZoneAirHumRat - zn1HB.ZoneAirHumRat)) * hg * ReportingConstant; } else { AirflowNetworkReportData(ZN1).MultiZoneMixLatLossW += - std::abs(AirflowNetworkLinkSimu(i).FLOW2 * - (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1) - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2))) * - hg; + std::abs(AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.ZoneAirHumRat - zn2HB.ZoneAirHumRat)) * hg; AirflowNetworkReportData(ZN1).MultiZoneMixLatLossJ += - (AirflowNetworkLinkSimu(i).FLOW2 * - (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1) - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2))) * - hg * ReportingConstant; + (AirflowNetworkLinkSimu(i).FLOW2 * (zn1HB.ZoneAirHumRat - zn2HB.ZoneAirHumRat)) * hg * ReportingConstant; } } } @@ -9060,6 +9015,7 @@ namespace AirflowNetwork { ZN2 = AirflowNetworkNodeData(M).EPlusZoneNum; // Find a linkage from a zone to outdoors if (ZN1 > 0 && ZN2 == 0) { + auto &zn1HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN1); if (AirflowNetworkNodeData(n).AirLoopNum > 0 && AirflowNetworkNodeData(n).AirLoopNum != AirLoopNum) continue; if (AirflowNetworkNodeData(n).AirLoopNum == AirLoopNum) { RepOnOffFanRunTimeFraction = LoopOnOffFanRunTimeFraction(AirLoopNum); @@ -9073,66 +9029,54 @@ namespace AirflowNetwork { CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat); if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR || AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) { - if (Tamb > m_state.dataHeatBalFanSys->MAT(ZN1)) { + if (Tamb > zn1HB.MAT) { AirflowNetworkReportData(ZN1).MultiZoneInfiSenGainW += - (linkReport1(i).FLOW2OFF * CpAir * (Tamb - m_state.dataHeatBalFanSys->MAT(ZN1))) * - (1.0 - RepOnOffFanRunTimeFraction); + (linkReport1(i).FLOW2OFF * CpAir * (Tamb - zn1HB.MAT)) * (1.0 - RepOnOffFanRunTimeFraction); AirflowNetworkReportData(ZN1).MultiZoneInfiSenGainJ += - (linkReport1(i).FLOW2OFF * CpAir * (Tamb - m_state.dataHeatBalFanSys->MAT(ZN1))) * ReportingConstant * - ReportingFraction; + (linkReport1(i).FLOW2OFF * CpAir * (Tamb - zn1HB.MAT)) * ReportingConstant * ReportingFraction; } else { AirflowNetworkReportData(ZN1).MultiZoneInfiSenLossW += - (linkReport1(i).FLOW2OFF * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN1) - Tamb)) * - (1.0 - RepOnOffFanRunTimeFraction); + (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - Tamb)) * (1.0 - RepOnOffFanRunTimeFraction); AirflowNetworkReportData(ZN1).MultiZoneInfiSenLossJ += - (linkReport1(i).FLOW2OFF * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN1) - Tamb)) * ReportingConstant * - ReportingFraction; + (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - Tamb)) * ReportingConstant * ReportingFraction; } - if (m_state.dataEnvrn->OutHumRat > m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1)) { + if (m_state.dataEnvrn->OutHumRat > zn1HB.ZoneAirHumRat) { AirflowNetworkReportData(ZN1).MultiZoneInfiLatGainW += - (linkReport1(i).FLOW2OFF * (m_state.dataEnvrn->OutHumRat - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1))) * - ReportingFraction; + (linkReport1(i).FLOW2OFF * (m_state.dataEnvrn->OutHumRat - zn1HB.ZoneAirHumRat)) * ReportingFraction; AirflowNetworkReportData(ZN1).MultiZoneInfiLatGainJ += - (linkReport1(i).FLOW2OFF * (m_state.dataEnvrn->OutHumRat - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1))) * - ReportingConstant * ReportingFraction; + (linkReport1(i).FLOW2OFF * (m_state.dataEnvrn->OutHumRat - zn1HB.ZoneAirHumRat)) * ReportingConstant * + ReportingFraction; } else { AirflowNetworkReportData(ZN1).MultiZoneInfiLatLossW += - (linkReport1(i).FLOW2OFF * (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1) - m_state.dataEnvrn->OutHumRat)) * - ReportingFraction; + (linkReport1(i).FLOW2OFF * (zn1HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingFraction; AirflowNetworkReportData(ZN1).MultiZoneInfiLatLossJ += - (linkReport1(i).FLOW2OFF * (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1) - m_state.dataEnvrn->OutHumRat)) * - ReportingConstant * ReportingFraction; + (linkReport1(i).FLOW2OFF * (zn1HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingConstant * + ReportingFraction; } } else { - if (Tamb > m_state.dataHeatBalFanSys->MAT(ZN1)) { + if (Tamb > zn1HB.MAT) { AirflowNetworkReportData(ZN1).MultiZoneVentSenGainW += - (linkReport1(i).FLOW2OFF * CpAir * (Tamb - m_state.dataHeatBalFanSys->MAT(ZN1))) * - (1.0 - RepOnOffFanRunTimeFraction); + (linkReport1(i).FLOW2OFF * CpAir * (Tamb - zn1HB.MAT)) * (1.0 - RepOnOffFanRunTimeFraction); AirflowNetworkReportData(ZN1).MultiZoneVentSenGainJ += - (linkReport1(i).FLOW2OFF * CpAir * (Tamb - m_state.dataHeatBalFanSys->MAT(ZN1))) * ReportingConstant * - ReportingFraction; + (linkReport1(i).FLOW2OFF * CpAir * (Tamb - zn1HB.MAT)) * ReportingConstant * ReportingFraction; } else { AirflowNetworkReportData(ZN1).MultiZoneVentSenLossW += - (linkReport1(i).FLOW2OFF * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN1) - Tamb)) * - (1.0 - RepOnOffFanRunTimeFraction); + (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - Tamb)) * (1.0 - RepOnOffFanRunTimeFraction); AirflowNetworkReportData(ZN1).MultiZoneVentSenLossJ += - (linkReport1(i).FLOW2OFF * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN1) - Tamb)) * ReportingConstant * - ReportingFraction; + (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - Tamb)) * ReportingConstant * ReportingFraction; } - if (m_state.dataEnvrn->OutHumRat > m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1)) { + if (m_state.dataEnvrn->OutHumRat > zn1HB.ZoneAirHumRat) { AirflowNetworkReportData(ZN1).MultiZoneVentLatGainW += - (linkReport1(i).FLOW2OFF * (m_state.dataEnvrn->OutHumRat - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1))) * - ReportingFraction; + (linkReport1(i).FLOW2OFF * (m_state.dataEnvrn->OutHumRat - zn1HB.ZoneAirHumRat)) * ReportingFraction; AirflowNetworkReportData(ZN1).MultiZoneVentLatGainJ += - (linkReport1(i).FLOW2OFF * (m_state.dataEnvrn->OutHumRat - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1))) * - ReportingConstant * ReportingFraction; + (linkReport1(i).FLOW2OFF * (m_state.dataEnvrn->OutHumRat - zn1HB.ZoneAirHumRat)) * ReportingConstant * + ReportingFraction; } else { AirflowNetworkReportData(ZN1).MultiZoneVentLatLossW += - (linkReport1(i).FLOW2OFF * (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1) - m_state.dataEnvrn->OutHumRat)) * - ReportingFraction; + (linkReport1(i).FLOW2OFF * (zn1HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingFraction; AirflowNetworkReportData(ZN1).MultiZoneVentLatLossJ += - (linkReport1(i).FLOW2OFF * (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1) - m_state.dataEnvrn->OutHumRat)) * - ReportingConstant * ReportingFraction; + (linkReport1(i).FLOW2OFF * (zn1HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingConstant * + ReportingFraction; } } if (AirflowNetworkNodeData(n).AirLoopNum == 0) { @@ -9140,6 +9084,7 @@ namespace AirflowNetwork { } } if (ZN1 == 0 && ZN2 > 0) { + auto &zn2HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN2); if (AirflowNetworkNodeData(M).AirLoopNum > 0 && AirflowNetworkNodeData(M).AirLoopNum != AirLoopNum) continue; if (AirflowNetworkNodeData(M).AirLoopNum == AirLoopNum) { RepOnOffFanRunTimeFraction = LoopOnOffFanRunTimeFraction(AirLoopNum); @@ -9153,62 +9098,54 @@ namespace AirflowNetwork { CpAir = PsyCpAirFnW(m_state.dataEnvrn->OutHumRat); if (AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SCR || AirflowNetworkCompData(AirflowNetworkLinkageData(i).CompNum).CompTypeNum == iComponentTypeNum::SEL) { - if (Tamb > m_state.dataHeatBalFanSys->MAT(ZN2)) { + if (Tamb > zn2HB.MAT) { AirflowNetworkReportData(ZN2).MultiZoneInfiSenGainW += - (linkReport1(i).FLOWOFF * CpAir * (Tamb - m_state.dataHeatBalFanSys->MAT(ZN2))) * ReportingFraction; + (linkReport1(i).FLOWOFF * CpAir * (Tamb - zn2HB.MAT)) * ReportingFraction; AirflowNetworkReportData(ZN2).MultiZoneInfiSenGainJ += - (linkReport1(i).FLOWOFF * CpAir * (Tamb - m_state.dataHeatBalFanSys->MAT(ZN2))) * ReportingConstant * - ReportingFraction; + (linkReport1(i).FLOWOFF * CpAir * (Tamb - zn2HB.MAT)) * ReportingConstant * ReportingFraction; } else { AirflowNetworkReportData(ZN2).MultiZoneInfiSenLossW += - (linkReport1(i).FLOWOFF * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN2) - Tamb)) * ReportingFraction; + (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - Tamb)) * ReportingFraction; AirflowNetworkReportData(ZN2).MultiZoneInfiSenLossJ += - (linkReport1(i).FLOWOFF * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN2) - Tamb)) * ReportingConstant * - ReportingFraction; + (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - Tamb)) * ReportingConstant * ReportingFraction; } - if (m_state.dataEnvrn->OutHumRat > m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2)) { + if (m_state.dataEnvrn->OutHumRat > zn2HB.ZoneAirHumRat) { AirflowNetworkReportData(ZN2).MultiZoneInfiLatGainW += - (linkReport1(i).FLOWOFF * (m_state.dataEnvrn->OutHumRat - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2))) * - ReportingFraction; + (linkReport1(i).FLOWOFF * (m_state.dataEnvrn->OutHumRat - zn2HB.ZoneAirHumRat)) * ReportingFraction; AirflowNetworkReportData(ZN2).MultiZoneInfiLatGainJ += - (linkReport1(i).FLOWOFF * (m_state.dataEnvrn->OutHumRat - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2))) * - ReportingConstant * ReportingFraction; + (linkReport1(i).FLOWOFF * (m_state.dataEnvrn->OutHumRat - zn2HB.ZoneAirHumRat)) * ReportingConstant * + ReportingFraction; } else { AirflowNetworkReportData(ZN2).MultiZoneInfiLatLossW += - (linkReport1(i).FLOWOFF * (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2) - m_state.dataEnvrn->OutHumRat)) * - ReportingFraction; + (linkReport1(i).FLOWOFF * (zn2HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingFraction; AirflowNetworkReportData(ZN2).MultiZoneInfiLatLossJ += - (linkReport1(i).FLOWOFF * (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2) - m_state.dataEnvrn->OutHumRat)) * - ReportingConstant * ReportingFraction; + (linkReport1(i).FLOWOFF * (zn2HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingConstant * + ReportingFraction; } } else { - if (Tamb > m_state.dataHeatBalFanSys->MAT(ZN2)) { + if (Tamb > zn2HB.MAT) { AirflowNetworkReportData(ZN2).MultiZoneVentSenGainW += - (linkReport1(i).FLOWOFF * CpAir * (Tamb - m_state.dataHeatBalFanSys->MAT(ZN2))) * ReportingFraction; + (linkReport1(i).FLOWOFF * CpAir * (Tamb - zn2HB.MAT)) * ReportingFraction; AirflowNetworkReportData(ZN2).MultiZoneVentSenGainJ += - (linkReport1(i).FLOWOFF * CpAir * (Tamb - m_state.dataHeatBalFanSys->MAT(ZN2))) * ReportingConstant * - ReportingFraction; + (linkReport1(i).FLOWOFF * CpAir * (Tamb - zn2HB.MAT)) * ReportingConstant * ReportingFraction; } else { AirflowNetworkReportData(ZN2).MultiZoneVentSenLossW += - (linkReport1(i).FLOWOFF * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN2) - Tamb)) * ReportingFraction; + (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - Tamb)) * ReportingFraction; AirflowNetworkReportData(ZN2).MultiZoneVentSenLossJ += - (linkReport1(i).FLOWOFF * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN2) - Tamb)) * ReportingConstant * - ReportingFraction; + (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - Tamb)) * ReportingConstant * ReportingFraction; } - if (m_state.dataEnvrn->OutHumRat > m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2)) { + if (m_state.dataEnvrn->OutHumRat > zn2HB.ZoneAirHumRat) { AirflowNetworkReportData(ZN2).MultiZoneVentLatGainW += - (linkReport1(i).FLOWOFF * (m_state.dataEnvrn->OutHumRat - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2))) * - ReportingFraction; + (linkReport1(i).FLOWOFF * (m_state.dataEnvrn->OutHumRat - zn2HB.ZoneAirHumRat)) * ReportingFraction; AirflowNetworkReportData(ZN2).MultiZoneVentLatGainJ += - (linkReport1(i).FLOWOFF * (m_state.dataEnvrn->OutHumRat - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2))) * - ReportingConstant * ReportingFraction; + (linkReport1(i).FLOWOFF * (m_state.dataEnvrn->OutHumRat - zn2HB.ZoneAirHumRat)) * ReportingConstant * + ReportingFraction; } else { AirflowNetworkReportData(ZN2).MultiZoneVentLatLossW += - (linkReport1(i).FLOWOFF * (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2) - m_state.dataEnvrn->OutHumRat)) * - ReportingFraction; + (linkReport1(i).FLOWOFF * (zn2HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingFraction; AirflowNetworkReportData(ZN2).MultiZoneVentLatLossJ += - (linkReport1(i).FLOWOFF * (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2) - m_state.dataEnvrn->OutHumRat)) * - ReportingConstant * ReportingFraction; + (linkReport1(i).FLOWOFF * (zn2HB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat)) * ReportingConstant * + ReportingFraction; } } if (AirflowNetworkNodeData(M).AirLoopNum == 0) { @@ -9217,77 +9154,55 @@ namespace AirflowNetwork { } if (ZN1 > 0 && ZN2 > 0) { + auto &zn1HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN1); + auto &zn2HB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZN2); ReportingFraction = (1.0 - MaxOnOffFanRunTimeFraction); - CpAir = PsyCpAirFnW(m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1)); - if (m_state.dataHeatBalFanSys->MAT(ZN1) > m_state.dataHeatBalFanSys->MAT(ZN2)) { + CpAir = PsyCpAirFnW(zn1HB.ZoneAirHumRat); + if (zn1HB.MAT > zn2HB.MAT) { AirflowNetworkReportData(ZN2).MultiZoneMixSenGainW += - (linkReport1(i).FLOWOFF * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN1) - m_state.dataHeatBalFanSys->MAT(ZN2))) * - ReportingFraction; + (linkReport1(i).FLOWOFF * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingFraction; AirflowNetworkReportData(ZN2).MultiZoneMixSenGainJ += - (linkReport1(i).FLOWOFF * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN1) - m_state.dataHeatBalFanSys->MAT(ZN2))) * - ReportingConstant * ReportingFraction; + (linkReport1(i).FLOWOFF * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingConstant * ReportingFraction; } else { AirflowNetworkReportData(ZN2).MultiZoneMixSenLossW += - (linkReport1(i).FLOWOFF * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN2) - m_state.dataHeatBalFanSys->MAT(ZN1))) * - ReportingFraction; + (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingFraction; AirflowNetworkReportData(ZN2).MultiZoneMixSenLossJ += - (linkReport1(i).FLOWOFF * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN2) - m_state.dataHeatBalFanSys->MAT(ZN1))) * - ReportingConstant * ReportingFraction; + (linkReport1(i).FLOWOFF * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingConstant * ReportingFraction; } - if (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1) > m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2)) { + if (zn1HB.ZoneAirHumRat > zn2HB.ZoneAirHumRat) { AirflowNetworkReportData(ZN2).MultiZoneMixLatGainW += - (linkReport1(i).FLOWOFF * - (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1) - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2))) * - ReportingFraction; + (linkReport1(i).FLOWOFF * (zn1HB.ZoneAirHumRat - zn2HB.ZoneAirHumRat)) * ReportingFraction; AirflowNetworkReportData(ZN2).MultiZoneMixLatGainJ += - (linkReport1(i).FLOWOFF * - (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1) - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2))) * - ReportingConstant * ReportingFraction; + (linkReport1(i).FLOWOFF * (zn1HB.ZoneAirHumRat - zn2HB.ZoneAirHumRat)) * ReportingConstant * ReportingFraction; } else { AirflowNetworkReportData(ZN2).MultiZoneMixLatLossW += - (linkReport1(i).FLOWOFF * - (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2) - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1))) * - ReportingFraction; + (linkReport1(i).FLOWOFF * (zn2HB.ZoneAirHumRat - zn1HB.ZoneAirHumRat)) * ReportingFraction; AirflowNetworkReportData(ZN2).MultiZoneMixLatLossJ += - (linkReport1(i).FLOWOFF * - (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2) - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1))) * - ReportingConstant * ReportingFraction; + (linkReport1(i).FLOWOFF * (zn2HB.ZoneAirHumRat - zn1HB.ZoneAirHumRat)) * ReportingConstant * ReportingFraction; } - CpAir = PsyCpAirFnW(m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2)); - if (m_state.dataHeatBalFanSys->MAT(ZN2) > m_state.dataHeatBalFanSys->MAT(ZN1)) { + CpAir = PsyCpAirFnW(zn2HB.ZoneAirHumRat); + if (zn2HB.MAT > zn1HB.MAT) { AirflowNetworkReportData(ZN1).MultiZoneMixSenGainW += - (linkReport1(i).FLOW2OFF * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN2) - m_state.dataHeatBalFanSys->MAT(ZN1))) * - ReportingFraction; + (linkReport1(i).FLOW2OFF * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingFraction; AirflowNetworkReportData(ZN1).MultiZoneMixSenGainJ += - (linkReport1(i).FLOW2OFF * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN2) - m_state.dataHeatBalFanSys->MAT(ZN1))) * - ReportingConstant * ReportingFraction; + (linkReport1(i).FLOW2OFF * CpAir * (zn2HB.MAT - zn1HB.MAT)) * ReportingConstant * ReportingFraction; } else { AirflowNetworkReportData(ZN1).MultiZoneMixSenLossW += - (linkReport1(i).FLOW2OFF * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN1) - m_state.dataHeatBalFanSys->MAT(ZN2))) * - ReportingFraction; + (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingFraction; AirflowNetworkReportData(ZN1).MultiZoneMixSenLossJ += - (linkReport1(i).FLOW2OFF * CpAir * (m_state.dataHeatBalFanSys->MAT(ZN1) - m_state.dataHeatBalFanSys->MAT(ZN2))) * - ReportingConstant * ReportingFraction; + (linkReport1(i).FLOW2OFF * CpAir * (zn1HB.MAT - zn2HB.MAT)) * ReportingConstant * ReportingFraction; } - if (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2) > m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1)) { + if (zn2HB.ZoneAirHumRat > zn1HB.ZoneAirHumRat) { AirflowNetworkReportData(ZN1).MultiZoneMixLatGainW += - (linkReport1(i).FLOW2OFF * - (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2) - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1))) * - ReportingFraction; + (linkReport1(i).FLOW2OFF * (zn2HB.ZoneAirHumRat - zn1HB.ZoneAirHumRat)) * ReportingFraction; AirflowNetworkReportData(ZN1).MultiZoneMixLatGainJ += - (linkReport1(i).FLOW2OFF * - (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2) - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1))) * - ReportingConstant * ReportingFraction; + (linkReport1(i).FLOW2OFF * (zn2HB.ZoneAirHumRat - zn1HB.ZoneAirHumRat)) * ReportingConstant * ReportingFraction; } else { AirflowNetworkReportData(ZN1).MultiZoneMixLatLossW += - std::abs(linkReport1(i).FLOW2OFF * - (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1) - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2))) * - ReportingFraction; + std::abs(linkReport1(i).FLOW2OFF * (zn1HB.ZoneAirHumRat - zn2HB.ZoneAirHumRat)) * ReportingFraction; AirflowNetworkReportData(ZN1).MultiZoneMixLatLossJ += - (linkReport1(i).FLOW2OFF * - (m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN1) - m_state.dataHeatBalFanSys->ZoneAirHumRat(ZN2))) * - ReportingConstant * ReportingFraction; + (linkReport1(i).FLOW2OFF * (zn1HB.ZoneAirHumRat - zn2HB.ZoneAirHumRat)) * ReportingConstant * ReportingFraction; } } } @@ -9299,10 +9214,10 @@ namespace AirflowNetwork { } for (i = 1; i <= m_state.dataGlobal->NumOfZones; ++i) { // Start of zone loads report variable update loop ... + auto &thisZoneHB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(i); Tamb = Zone(i).OutDryBulbTemp; - CpAir = PsyCpAirFnW(m_state.dataHeatBalFanSys->ZoneAirHumRatAvg(i)); - AirDensity = PsyRhoAirFnPbTdbW( - m_state, m_state.dataEnvrn->OutBaroPress, m_state.dataHeatBalFanSys->MAT(i), m_state.dataHeatBalFanSys->ZoneAirHumRatAvg(i)); + CpAir = PsyCpAirFnW(thisZoneHB.ZoneAirHumRatAvg); + AirDensity = PsyRhoAirFnPbTdbW(m_state, m_state.dataEnvrn->OutBaroPress, thisZoneHB.MAT, thisZoneHB.ZoneAirHumRatAvg); AirflowNetworkZnRpt(i).InfilMass = (exchangeData(i).SumMCp / CpAir) * ReportingConstant; AirflowNetworkZnRpt(i).InfilVolume = AirflowNetworkZnRpt(i).InfilMass / AirDensity; @@ -9349,10 +9264,9 @@ namespace AirflowNetwork { } AirflowNetworkZnRpt(i).ExfilMass = AirflowNetworkZnRpt(i).InfilMass + AirflowNetworkZnRpt(i).VentilMass + AirflowNetworkZnRpt(i).MixMass + AirflowNetworkZnRpt(i).InletMass - AirflowNetworkZnRpt(i).OutletMass; - AirflowNetworkZnRpt(i).ExfilSensiLoss = - AirflowNetworkZnRpt(i).ExfilMass / ReportingConstant * (m_state.dataHeatBalFanSys->MAT(i) - Tamb) * CpAir; - AirflowNetworkZnRpt(i).ExfilLatentLoss = AirflowNetworkZnRpt(i).ExfilMass / ReportingConstant * - (m_state.dataHeatBalFanSys->ZoneAirHumRat(i) - m_state.dataEnvrn->OutHumRat) * H2OHtOfVap; + AirflowNetworkZnRpt(i).ExfilSensiLoss = AirflowNetworkZnRpt(i).ExfilMass / ReportingConstant * (thisZoneHB.MAT - Tamb) * CpAir; + AirflowNetworkZnRpt(i).ExfilLatentLoss = + AirflowNetworkZnRpt(i).ExfilMass / ReportingConstant * (thisZoneHB.ZoneAirHumRat - m_state.dataEnvrn->OutHumRat) * H2OHtOfVap; AirflowNetworkZnRpt(i).ExfilTotalLoss = AirflowNetworkZnRpt(i).ExfilSensiLoss + AirflowNetworkZnRpt(i).ExfilLatentLoss; m_state.dataHeatBal->ZoneTotalExfiltrationHeatLoss += AirflowNetworkZnRpt(i).ExfilTotalLoss * ReportingConstant; @@ -11871,29 +11785,18 @@ namespace AirflowNetwork { // SUBROUTINE INFORMATION: // AUTHOR Lixing Gu // DATE WRITTEN May. 2007 - // MODIFIED na - // RE-ENGINEERED na // PURPOSE OF THIS SUBROUTINE: // This function outputs air change per hour in a given zone - // Using/Aliasing auto &TimeStepSys = m_state.dataHVACGlobal->TimeStepSys; + auto &thisZoneHB = m_state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); - // Return value - Real64 ACH; // Zone air change rate [ACH] - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - Real64 InfilVolume; // Zone infiltration volume - Real64 RhoAir; // Zone air density [kg/m3] - Real64 CpAir; // Zone air specific heat - - CpAir = PsyCpAirFnW(m_state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)); - RhoAir = PsyRhoAirFnPbTdbW( - m_state, m_state.dataEnvrn->OutBaroPress, m_state.dataHeatBalFanSys->MAT(ZoneNum), m_state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)); - InfilVolume = + Real64 CpAir = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat); + Real64 RhoAir = PsyRhoAirFnPbTdbW(m_state, m_state.dataEnvrn->OutBaroPress, thisZoneHB.MAT, thisZoneHB.ZoneAirHumRat); + Real64 InfilVolume = ((exchangeData(ZoneNum).SumMCp + exchangeData(ZoneNum).SumMVCp) / CpAir / RhoAir) * TimeStepSys * DataGlobalConstants::SecInHour; - ACH = InfilVolume / (TimeStepSys * m_state.dataHeatBal->Zone(ZoneNum).Volume); + Real64 ACH = InfilVolume / (TimeStepSys * m_state.dataHeatBal->Zone(ZoneNum).Volume); return ACH; } @@ -12979,7 +12882,7 @@ namespace AirflowNetwork { if (MinTimeControlOnly) return; - if (Zone(ZoneNum).HasLinkedOutAirNode) { + if (Zone(ZoneNum).LinkedOutAirNode > 0) { OutDryBulb = Zone(ZoneNum).OutDryBulbTemp; } else { OutDryBulb = OutDryBulbTempAt(state, Zone(ZoneNum).Centroid.z); @@ -12991,7 +12894,7 @@ namespace AirflowNetwork { Tcomfort = CurveValue(state, ComfortHighTempCurveNum, OutDryBulb); } ComfortBand = -0.0028 * (100 - MaxPPD) * (100 - MaxPPD) + 0.3419 * (100 - MaxPPD) - 6.6275; - Toperative = 0.5 * (state.dataHeatBalFanSys->MAT(ZoneNum) + state.dataHeatBal->ZoneMRT(ZoneNum)); + Toperative = 0.5 * (state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT + state.dataHeatBal->ZoneMRT(ZoneNum)); if (Toperative > (Tcomfort + ComfortBand)) { if (opening_probability(state, ZoneNum, TimeCloseDuration)) { @@ -13022,6 +12925,7 @@ namespace AirflowNetwork { { Real64 SchValue; Real64 RandomValue; + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); if (TimeCloseDuration < MinClosingTime) { return false; @@ -13034,20 +12938,20 @@ namespace AirflowNetwork { switch (state.dataHeatBalFanSys->TempControlType(ZoneNum)) { case DataHVACGlobals::ThermostatType::SingleHeating: - if (state.dataHeatBalFanSys->MAT(ZoneNum) <= state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ZoneNum)) { + if (thisZoneHB.MAT <= state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ZoneNum)) { return false; } break; case DataHVACGlobals::ThermostatType::SingleCooling: - if (state.dataHeatBalFanSys->MAT(ZoneNum) >= state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ZoneNum)) { + if (thisZoneHB.MAT >= state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ZoneNum)) { return false; } break; case DataHVACGlobals::ThermostatType::SingleHeatCool: return false; case DataHVACGlobals::ThermostatType::DualSetPointWithDeadBand: - if (state.dataHeatBalFanSys->MAT(ZoneNum) < state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ZoneNum) || - state.dataHeatBalFanSys->MAT(ZoneNum) > state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ZoneNum)) { + if (thisZoneHB.MAT < state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ZoneNum) || + thisZoneHB.MAT > state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ZoneNum)) { return false; } break; diff --git a/src/EnergyPlus/CMakeLists.txt b/src/EnergyPlus/CMakeLists.txt index e2f6b9392b7..c500bc62810 100644 --- a/src/EnergyPlus/CMakeLists.txt +++ b/src/EnergyPlus/CMakeLists.txt @@ -223,6 +223,7 @@ set(SRC DataWater.hh DataWindowEquivalentLayer.hh DataZoneControls.hh + DataZoneEnergyDemands.cc DataZoneEnergyDemands.hh DataZoneEquipment.cc DataZoneEquipment.hh diff --git a/src/EnergyPlus/ChilledCeilingPanelSimple.cc b/src/EnergyPlus/ChilledCeilingPanelSimple.cc index be911da3ddc..3c39c1a5075 100644 --- a/src/EnergyPlus/ChilledCeilingPanelSimple.cc +++ b/src/EnergyPlus/ChilledCeilingPanelSimple.cc @@ -78,6 +78,7 @@ #include #include #include +#include namespace EnergyPlus::CoolingPanelSimple { @@ -848,7 +849,7 @@ void InitCoolingPanel(EnergyPlusData &state, int const CoolingPanelNum, int cons if (state.dataGlobal->BeginTimeStepFlag && FirstHVACIteration) { int ZoneNum = ThisCP.ZonePtr; - state.dataHeatBal->Zone(ZoneNum).ZeroSourceSumHATsurf = SumHATsurf(state, ZoneNum); + state.dataHeatBal->Zone(ZoneNum).ZeroSourceSumHATsurf = state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state); ThisCP.CoolingPanelSrcAvg = 0.0; ThisCP.LastCoolingPanelSrc = 0.0; ThisCP.LastSysTimeElapsed = 0.0; @@ -1241,7 +1242,7 @@ void CoolingPanelParams::CalcCoolingPanel(EnergyPlusData &state, int const Cooli CoolingPanelOn = false; } // Calculate the "zone" temperature for determining the output of the cooling panel - Tzone = Xr * state.dataHeatBal->ZoneMRT(ZoneNum) + ((1.0 - Xr) * state.dataHeatBalFanSys->MAT(ZoneNum)); + Tzone = Xr * state.dataHeatBal->ZoneMRT(ZoneNum) + ((1.0 - Xr) * state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT); // Logical controls: if the WaterInletTemperature is higher than Tzone, do not run the panel if (waterInletTemp >= Tzone) CoolingPanelOn = false; @@ -1256,7 +1257,7 @@ void CoolingPanelParams::CalcCoolingPanel(EnergyPlusData &state, int const Cooli // iterate like in the low temperature radiant systems because the inlet water condition is known // not calculated. So, we can deal with this upfront rather than after calculation and then more // iteration. - DewPointTemp = PsyTdpFnWPb(state, state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum), state.dataEnvrn->OutBaroPress); + DewPointTemp = PsyTdpFnWPb(state, state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZoneAirHumRat, state.dataEnvrn->OutBaroPress); if (waterInletTemp < (DewPointTemp + this->CondDewPtDeltaT) && (CoolingPanelOn)) { @@ -1429,8 +1430,8 @@ void CoolingPanelParams::CalcCoolingPanel(EnergyPlusData &state, int const Cooli // that all energy radiated to people is converted to convective energy is // not very precise, but at least it conserves energy. The system impact to heat balance // should include this. - LoadMet = (SumHATsurf(state, ZoneNum) - state.dataHeatBal->Zone(ZoneNum).ZeroSourceSumHATsurf) + (CoolingPanelCool * this->FracConvect) + - (RadHeat * this->FracDistribPerson); + LoadMet = (state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state) - state.dataHeatBal->Zone(ZoneNum).ZeroSourceSumHATsurf) + + (CoolingPanelCool * this->FracConvect) + (RadHeat * this->FracDistribPerson); } this->WaterOutletEnthalpy = this->WaterInletEnthalpy - CoolingPanelCool / waterMassFlowRate; @@ -1469,13 +1470,13 @@ Real64 CoolingPanelParams::getCoolingPanelControlTemp(EnergyPlusData &state, int switch (this->controlType) { case ClgPanelCtrlType::MAT: { - return state.dataHeatBalFanSys->MAT(ZoneNum); + return state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; } break; case ClgPanelCtrlType::MRT: { return state.dataHeatBal->ZoneMRT(ZoneNum); } break; case ClgPanelCtrlType::Operative: { - return 0.5 * (state.dataHeatBalFanSys->MAT(ZoneNum) + state.dataHeatBal->ZoneMRT(ZoneNum)); + return 0.5 * (state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT + state.dataHeatBal->ZoneMRT(ZoneNum)); } break; case ClgPanelCtrlType::ODB: { return state.dataHeatBal->Zone(ZoneNum).OutDryBulbTemp; @@ -1484,9 +1485,8 @@ Real64 CoolingPanelParams::getCoolingPanelControlTemp(EnergyPlusData &state, int return state.dataHeatBal->Zone(ZoneNum).OutWetBulbTemp; } break; default: { // Should never get here - ShowSevereError(state, "Illegal control type in cooling panel system: " + this->EquipID); - ShowFatalError(state, "Preceding condition causes termination."); - return -99990; // Compiler doesn't understand that a fatal error means the program will exit, so give an invalid value + assert(false); + return -99990; // Compiler wants a return value for every path, so give an invalid value } break; } } @@ -1685,62 +1685,4 @@ void CoolingPanelParams::ReportCoolingPanel(EnergyPlusData &state) this->RadEnergy = this->RadPower * TimeStepSys * DataGlobalConstants::SecInHour; } -Real64 SumHATsurf(EnergyPlusData &state, int const ZoneNum) // Zone number -{ - - // FUNCTION INFORMATION: - // AUTHOR Rick Strand - // DATE WRITTEN Aug 2014 - - // PURPOSE OF THIS FUNCTION: - // This function calculates the zone sum of Hc*Area*Tsurf. It replaces the old SUMHAT. - // The SumHATsurf code below is also in the CalcZoneSums subroutine in ZoneTempPredictorCorrector - // and should be updated accordingly. - - // REFERENCES: - // Existing code for hot water baseboard models (radiant-convective variety) - - // Using/Aliasing - using DataSurfaces::WinShadingType; - - // Return value - Real64 SumHATsurf; - - // FUNCTION LOCAL VARIABLE DECLARATIONS: - int SurfNum; // Surface number - Real64 Area; // Effective surface area - SumHATsurf = 0.0; - - for (SurfNum = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst; SurfNum <= state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast; ++SurfNum) { - - auto &ThisSurf(state.dataSurface->Surface(SurfNum)); - - Area = ThisSurf.Area; - - if (ThisSurf.Class == DataSurfaces::SurfaceClass::Window) { - - if (ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum))) { - // The area is the shade or blind area = the sum of the glazing area and the divider area (which is zero if no divider) - Area += state.dataSurface->SurfWinDividerArea(SurfNum); - } - - if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) { - // Window frame contribution - SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinFrameArea(SurfNum) * - (1.0 + state.dataSurface->SurfWinProjCorrFrIn(SurfNum)) * state.dataSurface->SurfWinFrameTempIn(SurfNum); - } - - if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0 && !ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum))) { - // Window divider contribution (only from shade or blind for window with divider and interior shade or blind) - SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinDividerArea(SurfNum) * - (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) * state.dataSurface->SurfWinDividerTempIn(SurfNum); - } - } - - SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * Area * state.dataHeatBalSurf->SurfTempInTmp(SurfNum); - } - - return SumHATsurf; -} - } // namespace EnergyPlus::CoolingPanelSimple diff --git a/src/EnergyPlus/ChilledCeilingPanelSimple.hh b/src/EnergyPlus/ChilledCeilingPanelSimple.hh index 02d9b32a5e2..14a9ca198a3 100644 --- a/src/EnergyPlus/ChilledCeilingPanelSimple.hh +++ b/src/EnergyPlus/ChilledCeilingPanelSimple.hh @@ -181,8 +181,6 @@ namespace CoolingPanelSimple { void DistributeCoolingPanelRadGains(EnergyPlusData &state); - Real64 SumHATsurf(EnergyPlusData &state, int ZoneNum); // Zone number - } // namespace CoolingPanelSimple struct ChilledCeilingPanelSimpleData : BaseGlobalStruct diff --git a/src/EnergyPlus/ChillerElectricASHRAE205.cc b/src/EnergyPlus/ChillerElectricASHRAE205.cc index 477f5aebe7e..699419d5fbb 100644 --- a/src/EnergyPlus/ChillerElectricASHRAE205.cc +++ b/src/EnergyPlus/ChillerElectricASHRAE205.cc @@ -62,7 +62,6 @@ #include #include #include -#include #include #include #include @@ -85,6 +84,7 @@ #include #include #include +#include namespace EnergyPlus::ChillerElectricASHRAE205 { @@ -597,7 +597,7 @@ void ASHRAE205ChillerSpecs::initialize(EnergyPlusData &state, bool const RunFlag break; } case AmbientTempIndicator::TempZone: { - this->AmbientTemp = state.dataHeatBalFanSys->MAT(this->AmbientTempZone); + this->AmbientTemp = state.dataZoneTempPredictorCorrector->zoneHeatBalance(this->AmbientTempZone).MAT; break; } case AmbientTempIndicator::OutsideAir: { diff --git a/src/EnergyPlus/ConvectionCoefficients.cc b/src/EnergyPlus/ConvectionCoefficients.cc index e4b637adfb9..b6b0467eac4 100644 --- a/src/EnergyPlus/ConvectionCoefficients.cc +++ b/src/EnergyPlus/ConvectionCoefficients.cc @@ -69,13 +69,13 @@ #include #include #include -#include #include #include #include #include #include #include +#include #include #include #include @@ -85,6 +85,7 @@ #include #include #include +#include namespace EnergyPlus::ConvectionCoefficients { @@ -304,95 +305,104 @@ void InitInteriorConvectionCoeffs(EnergyPlusData &state, } } for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { - for (int SurfNum = Zone(ZoneNum).HTSurfaceFirst; SurfNum <= Zone(ZoneNum).HTSurfaceLast; ++SurfNum) { + if (present(ZoneToResimulate)) { + if ((ZoneNum != ZoneToResimulate) && (state.dataSurface->SurfAdjacentZone(SurfNum) != ZoneToResimulate)) { + continue; // skip surfaces that are not associated with this zone + } + } + auto &surface(Surface(SurfNum)); + if (state.dataSurface->UseRepresentativeSurfaceCalculations) { + int repSurfNum = surface.RepresentativeCalcSurfNum; + if (SurfNum != repSurfNum) continue; + } - if (present(ZoneToResimulate)) { - if ((ZoneNum != ZoneToResimulate) && (state.dataSurface->SurfAdjacentZone(SurfNum) != ZoneToResimulate)) { - continue; // skip surfaces that are not associated with this zone + int algoNum; + bool standardAlgo; + if (state.dataSurface->SurfIntConvCoeffIndex(SurfNum) <= -1) { // Set by user using one of the standard algorithms... + algoNum = std::abs(state.dataSurface->SurfIntConvCoeffIndex(SurfNum)); + standardAlgo = true; + } else if (state.dataSurface->SurfIntConvCoeffIndex(SurfNum) == + ConvectionConstants::HcInt_SetByZone) { // Not set by user, uses Zone Setting + algoNum = Zone(ZoneNum).InsideConvectionAlgo; + standardAlgo = true; + } else { + algoNum = Zone(ZoneNum).InsideConvectionAlgo; + standardAlgo = false; } - } - auto &surface(Surface(SurfNum)); - if (state.dataSurface->UseRepresentativeSurfaceCalculations) { - int repSurfNum = surface.RepresentativeCalcSurfNum; - if (SurfNum != repSurfNum) continue; - } - int algoNum; - bool standardAlgo; - if (state.dataSurface->SurfIntConvCoeffIndex(SurfNum) <= -1) { // Set by user using one of the standard algorithms... - algoNum = std::abs(state.dataSurface->SurfIntConvCoeffIndex(SurfNum)); - standardAlgo = true; - } else if (state.dataSurface->SurfIntConvCoeffIndex(SurfNum) == - ConvectionConstants::HcInt_SetByZone) { // Not set by user, uses Zone Setting - algoNum = Zone(ZoneNum).InsideConvectionAlgo; - standardAlgo = true; - } else { - algoNum = Zone(ZoneNum).InsideConvectionAlgo; - standardAlgo = false; - } + if (standardAlgo) { + switch (algoNum) { + case ConvectionConstants::HcInt_ASHRAESimple: { + CalcASHRAESimpleIntConvCoeff( + state, SurfNum, SurfaceTemperatures(SurfNum), state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT); + // Establish some lower limit to avoid a zero convection coefficient (and potential divide by zero problems) + if (state.dataHeatBalSurf->SurfHConvInt(SurfNum) < state.dataHeatBal->LowHConvLimit) + state.dataHeatBalSurf->SurfHConvInt(SurfNum) = state.dataHeatBal->LowHConvLimit; + } break; + case ConvectionConstants::HcInt_ASHRAETARP: { + if (!state.dataConstruction->Construct(Surface(SurfNum).Construction).TypeIsWindow) { + CalcASHRAEDetailedIntConvCoeff( + state, SurfNum, SurfaceTemperatures(SurfNum), state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT); + } else { + CalcISO15099WindowIntConvCoeff( + state, SurfNum, SurfaceTemperatures(SurfNum), state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT); + } - if (standardAlgo) { - switch (algoNum) { - case ConvectionConstants::HcInt_ASHRAESimple: { - CalcASHRAESimpleIntConvCoeff(state, SurfNum, SurfaceTemperatures(SurfNum), state.dataHeatBalFanSys->MAT(ZoneNum)); - // Establish some lower limit to avoid a zero convection coefficient (and potential divide by zero problems) - if (state.dataHeatBalSurf->SurfHConvInt(SurfNum) < state.dataHeatBal->LowHConvLimit) - state.dataHeatBalSurf->SurfHConvInt(SurfNum) = state.dataHeatBal->LowHConvLimit; - } break; - case ConvectionConstants::HcInt_ASHRAETARP: { - if (!state.dataConstruction->Construct(Surface(SurfNum).Construction).TypeIsWindow) { - CalcASHRAEDetailedIntConvCoeff(state, SurfNum, SurfaceTemperatures(SurfNum), state.dataHeatBalFanSys->MAT(ZoneNum)); - } else { - CalcISO15099WindowIntConvCoeff(state, SurfNum, SurfaceTemperatures(SurfNum), state.dataHeatBalFanSys->MAT(ZoneNum)); + // Establish some lower limit to avoid a zero convection coefficient (and potential divide by zero problems) + if (state.dataHeatBalSurf->SurfHConvInt(SurfNum) < state.dataHeatBal->LowHConvLimit) + state.dataHeatBalSurf->SurfHConvInt(SurfNum) = state.dataHeatBal->LowHConvLimit; + } break; + case ConvectionConstants::HcInt_AdaptiveConvectionAlgorithm: { + ManageInsideAdaptiveConvectionAlgo(state, SurfNum); + } break; + case ConvectionConstants::HcInt_CeilingDiffuser: + case ConvectionConstants::HcInt_TrombeWall: { + // Already done above and can't be at individual surface + } break; + case ConvectionConstants::HcInt_ASTMC1340: { + CalcASTMC1340ConvCoeff( + state, SurfNum, SurfaceTemperatures(SurfNum), state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT); + } break; + default: { + ShowFatalError(state, "Unhandled convection coefficient algorithm."); + } break; } + } else { // Interior convection has been set by the user with "value" or "schedule" + state.dataHeatBalSurf->SurfHConvInt(SurfNum) = SetIntConvectionCoeff(state, SurfNum); // Establish some lower limit to avoid a zero convection coefficient (and potential divide by zero problems) if (state.dataHeatBalSurf->SurfHConvInt(SurfNum) < state.dataHeatBal->LowHConvLimit) state.dataHeatBalSurf->SurfHConvInt(SurfNum) = state.dataHeatBal->LowHConvLimit; - } break; - case ConvectionConstants::HcInt_AdaptiveConvectionAlgorithm: { - ManageInsideAdaptiveConvectionAlgo(state, SurfNum); - } break; - case ConvectionConstants::HcInt_CeilingDiffuser: - case ConvectionConstants::HcInt_TrombeWall: { - // Already done above and can't be at individual surface - } break; - case ConvectionConstants::HcInt_ASTMC1340: { - CalcASTMC1340ConvCoeff(state, SurfNum, SurfaceTemperatures(SurfNum), state.dataHeatBalFanSys->MAT(ZoneNum)); - } break; - default: { - ShowFatalError(state, "Unhandled convection coefficient algorithm."); - } break; } - } else { // Interior convection has been set by the user with "value" or "schedule" - state.dataHeatBalSurf->SurfHConvInt(SurfNum) = SetIntConvectionCoeff(state, SurfNum); - // Establish some lower limit to avoid a zero convection coefficient (and potential divide by zero problems) - if (state.dataHeatBalSurf->SurfHConvInt(SurfNum) < state.dataHeatBal->LowHConvLimit) - state.dataHeatBalSurf->SurfHConvInt(SurfNum) = state.dataHeatBal->LowHConvLimit; - } - - if (state.dataSurface->SurfEMSOverrideIntConvCoef(SurfNum)) { - state.dataHeatBalSurf->SurfHConvInt(SurfNum) = state.dataSurface->SurfEMSValueForIntConvCoef(SurfNum); - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { - Real64 hConst = state.dataSurface->SurfEMSValueForIntConvCoef(SurfNum); - state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].in = KIVA_CONST_CONV(hConst); + if (state.dataSurface->SurfEMSOverrideIntConvCoef(SurfNum)) { + state.dataHeatBalSurf->SurfHConvInt(SurfNum) = state.dataSurface->SurfEMSValueForIntConvCoef(SurfNum); + if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + Real64 hConst = state.dataSurface->SurfEMSValueForIntConvCoef(SurfNum); + state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].in = KIVA_CONST_CONV(hConst); + } } } } } for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { - for (int SurfNum = Zone(ZoneNum).WindowSurfaceFirst; SurfNum <= Zone(ZoneNum).WindowSurfaceLast; ++SurfNum) { - auto &surface(Surface(SurfNum)); - if (state.dataSurface->UseRepresentativeSurfaceCalculations) { - int repSurfNum = surface.RepresentativeCalcSurfNum; - if (SurfNum != repSurfNum) continue; - } - if (Surface(SurfNum).ExtBoundCond == ExternalEnvironment) { - state.dataHeatBalSurf->SurfHConvInt(SurfNum) = - state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataHeatBalSurf->SurfWinCoeffAdjRatio(SurfNum); + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int SurfNum = thisSpace.WindowSurfaceFirst; SurfNum <= thisSpace.WindowSurfaceLast; ++SurfNum) { + auto &surface(Surface(SurfNum)); + if (state.dataSurface->UseRepresentativeSurfaceCalculations) { + int repSurfNum = surface.RepresentativeCalcSurfNum; + if (SurfNum != repSurfNum) continue; + } + if (Surface(SurfNum).ExtBoundCond == ExternalEnvironment) { + state.dataHeatBalSurf->SurfHConvInt(SurfNum) = + state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataHeatBalSurf->SurfWinCoeffAdjRatio(SurfNum); + } } } } @@ -3214,10 +3224,11 @@ void CalcDetailedHcInForDVModel(EnergyPlusData &state, TAirConv = state.dataHeatBal->SurfTempEffBulkAir(SurfNum); } else { // currently set to mean air temp but should add error warning here - TAirConv = state.dataHeatBalFanSys->MAT(Surface(SurfNum).Zone); + TAirConv = state.dataZoneTempPredictorCorrector->zoneHeatBalance(Surface(SurfNum).Zone).MAT; } } + assert(state.dataRoomAirMod->AirModel.allocated()); if (state.dataRoomAirMod->AirModel(Surface(SurfNum).Zone).AirModelType == DataRoomAirModel::RoomAirModel::UCSDDV || state.dataRoomAirMod->AirModel(Surface(SurfNum).Zone).AirModelType == DataRoomAirModel::RoomAirModel::UCSDUFI || state.dataRoomAirMod->AirModel(Surface(SurfNum).Zone).AirModelType == DataRoomAirModel::RoomAirModel::UCSDUFE) { @@ -3409,36 +3420,38 @@ void CalcCeilingDiffuserIntConvCoeff(EnergyPlusData &state, const Array1D &SurfaceTemperatures) // zone number for which coefficients are being calculated { - auto &Zone(state.dataHeatBal->Zone); auto &Surface(state.dataSurface->Surface); Real64 ACH = CalcCeilingDiffuserACH(state, ZoneNum); - Real64 AirHumRat = state.dataHeatBalFanSys->ZoneAirHumRatAvg(ZoneNum); + Real64 AirHumRat = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZoneAirHumRatAvg; - for (auto SurfNum = Zone(ZoneNum).HTSurfaceFirst; SurfNum <= Zone(ZoneNum).HTSurfaceLast; ++SurfNum) { - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { - Real64 height = state.dataSurface->Surface(SurfNum).Height; - bool isWindow = state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).TypeIsWindow; - state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].in = - [=, &state](double Tsurf, double Tamb, double, double, double cosTilt) -> double { - return CalcCeilingDiffuserIntConvCoeff(state, ACH, Tsurf, Tamb, cosTilt, AirHumRat, height, isWindow); - }; - } else { - state.dataHeatBalSurf->SurfHConvInt(SurfNum) = - CalcCeilingDiffuserIntConvCoeff(state, - ACH, - SurfaceTemperatures(SurfNum), - state.dataHeatBalFanSys->MAT(ZoneNum), - Surface(SurfNum).CosTilt, - AirHumRat, - Surface(SurfNum).Height, - state.dataConstruction->Construct(Surface(SurfNum).Construction).TypeIsWindow); - // Establish some lower limit to avoid a zero convection coefficient (and potential divide by zero problems) - if (state.dataHeatBalSurf->SurfHConvInt(SurfNum) < state.dataHeatBal->LowHConvLimit) - state.dataHeatBalSurf->SurfHConvInt(SurfNum) = state.dataHeatBal->LowHConvLimit; - } - } // SurfNum + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (auto SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { + if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + Real64 height = state.dataSurface->Surface(SurfNum).Height; + bool isWindow = state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).TypeIsWindow; + state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].in = + [=, &state](double Tsurf, double Tamb, double, double, double cosTilt) -> double { + return CalcCeilingDiffuserIntConvCoeff(state, ACH, Tsurf, Tamb, cosTilt, AirHumRat, height, isWindow); + }; + } else { + state.dataHeatBalSurf->SurfHConvInt(SurfNum) = + CalcCeilingDiffuserIntConvCoeff(state, + ACH, + SurfaceTemperatures(SurfNum), + state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT, + Surface(SurfNum).CosTilt, + AirHumRat, + Surface(SurfNum).Height, + state.dataConstruction->Construct(Surface(SurfNum).Construction).TypeIsWindow); + // Establish some lower limit to avoid a zero convection coefficient (and potential divide by zero problems) + if (state.dataHeatBalSurf->SurfHConvInt(SurfNum) < state.dataHeatBal->LowHConvLimit) + state.dataHeatBalSurf->SurfHConvInt(SurfNum) = state.dataHeatBal->LowHConvLimit; + } + } // SurfNum + } } // CalcCeilingDiffuserInletCorr should replace CalcCeilingDiffuser (above), if ZoneTempPredictorCorrector can @@ -3508,36 +3521,40 @@ void CalcCeilingDiffuserInletCorr(EnergyPlusData &state, } } - for (SurfNum = Zone(ZoneNum).HTSurfaceFirst; SurfNum <= Zone(ZoneNum).HTSurfaceLast; ++SurfNum) { - if (ACH <= 3.0) { // Use the other convection algorithm - if (!state.dataConstruction->Construct(Surface(SurfNum).Construction).TypeIsWindow) { - CalcASHRAEDetailedIntConvCoeff(state, SurfNum, SurfaceTemperatures(SurfNum), state.dataHeatBalFanSys->MAT(ZoneNum)); - } else { - CalcISO15099WindowIntConvCoeff(state, SurfNum, SurfaceTemperatures(SurfNum), state.dataHeatBalFanSys->MAT(ZoneNum)); - } - } else { // Use forced convection correlations - Tilt = Surface(SurfNum).Tilt; - - // assume that reference air temp for user defined convection coefficient is the mean air temperature (=MAT) - // Calculate the convection coefficient based on inlet (supply) air conditions - if (Tilt < 45.0) { - state.dataHeatBalSurf->SurfHConvInt(SurfNum) = 0.49 * std::pow(ACH, 0.8); // Ceiling correlation - } else if (Tilt > 135.0) { - state.dataHeatBalSurf->SurfHConvInt(SurfNum) = 0.13 * std::pow(ACH, 0.8); // Floor correlation - } else { - state.dataHeatBalSurf->SurfHConvInt(SurfNum) = 0.19 * std::pow(ACH, 0.8); // Wall correlation + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { + if (ACH <= 3.0) { // Use the other convection algorithm + if (!state.dataConstruction->Construct(Surface(SurfNum).Construction).TypeIsWindow) { + CalcASHRAEDetailedIntConvCoeff( + state, SurfNum, SurfaceTemperatures(SurfNum), state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT); + } else { + CalcISO15099WindowIntConvCoeff( + state, SurfNum, SurfaceTemperatures(SurfNum), state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT); + } + } else { // Use forced convection correlations + Tilt = Surface(SurfNum).Tilt; + + // assume that reference air temp for user defined convection coefficient is the mean air temperature (=MAT) + // Calculate the convection coefficient based on inlet (supply) air conditions + if (Tilt < 45.0) { + state.dataHeatBalSurf->SurfHConvInt(SurfNum) = 0.49 * std::pow(ACH, 0.8); // Ceiling correlation + } else if (Tilt > 135.0) { + state.dataHeatBalSurf->SurfHConvInt(SurfNum) = 0.13 * std::pow(ACH, 0.8); // Floor correlation + } else { + state.dataHeatBalSurf->SurfHConvInt(SurfNum) = 0.19 * std::pow(ACH, 0.8); // Wall correlation + } + // set flag for reference air temperature + state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneSupplyAirTemp; + state.dataSurface->SurfTAirRefRpt(SurfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(SurfNum)]; } - // set flag for reference air temperature - state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneSupplyAirTemp; - state.dataSurface->SurfTAirRefRpt(SurfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(SurfNum)]; - } - // Establish some lower limit to avoid a zero convection coefficient (and potential divide by zero problems) - if (state.dataHeatBalSurf->SurfHConvInt(SurfNum) < state.dataHeatBal->LowHConvLimit) - state.dataHeatBalSurf->SurfHConvInt(SurfNum) = state.dataHeatBal->LowHConvLimit; - - } // SurfNum + // Establish some lower limit to avoid a zero convection coefficient (and potential divide by zero problems) + if (state.dataHeatBalSurf->SurfHConvInt(SurfNum) < state.dataHeatBal->LowHConvLimit) + state.dataHeatBalSurf->SurfHConvInt(SurfNum) = state.dataHeatBal->LowHConvLimit; + } // SurfNum + } if (ACH > 100.0) ShowWarningError(state, "CeilingDiffuser convection correlation is out of range: ACH > 100"); } @@ -3549,16 +3566,11 @@ void CalcTrombeWallIntConvCoeff(EnergyPlusData &state, // SUBROUTINE INFORMATION: // AUTHOR Peter Graham Ellis - // DATE WRITTEN ????? - // MODIFIED na - // RE-ENGINEERED na // PURPOSE OF THIS FUNCTION: // This subroutine calculates the interior convection coefficient // using the Trombe Wall correlation ????? - // Using/Aliasing - // SUBROUTINE PARAMETER DEFINITIONS: constexpr Real64 g(9.81); // gravity constant (m/s**2) constexpr Real64 v(15.89e-6); // kinematic viscosity (m**2/s) for air at 300 K @@ -3569,9 +3581,8 @@ void CalcTrombeWallIntConvCoeff(EnergyPlusData &state, auto &Surface(state.dataSurface->Surface); // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int SurfNum; // DO loop counter for surfaces - int Surf1; // first major wall surface - int Surf2; // second major wall surface + int Surf1 = 0; // first major wall surface + int Surf2 = 0; // second major wall surface Real64 H; // height of enclosure Real64 minorW; // width of enclosure (narrow dimension) @@ -3594,9 +3605,6 @@ void CalcTrombeWallIntConvCoeff(EnergyPlusData &state, // are assumed to have exactly equal widths AND must have a greater // width than the side surfaces. - Surf1 = 0; - Surf2 = 0; - H = Zone(ZoneNum).CeilingHeight; minorW = 100000.0; // An impossibly big width majorW = 0.0; @@ -3607,29 +3615,32 @@ void CalcTrombeWallIntConvCoeff(EnergyPlusData &state, HConvNet = 0.0; // determine major width and minor width - for (SurfNum = Zone(ZoneNum).HTSurfaceFirst; SurfNum <= Zone(ZoneNum).HTSurfaceLast; ++SurfNum) { - if (Surface(SurfNum).Class != SurfaceClass::Wall) continue; + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { + if (Surface(SurfNum).Class != SurfaceClass::Wall) continue; - if (Surface(SurfNum).Width > majorW) { - majorW = Surface(SurfNum).Width; - } + if (Surface(SurfNum).Width > majorW) { + majorW = Surface(SurfNum).Width; + } - if (Surface(SurfNum).Width < minorW) { - minorW = Surface(SurfNum).Width; + if (Surface(SurfNum).Width < minorW) { + minorW = Surface(SurfNum).Width; + } } - } - // assign major surfaces - for (SurfNum = Zone(ZoneNum).HTSurfaceFirst; SurfNum <= Zone(ZoneNum).HTSurfaceLast; ++SurfNum) { - if (Surface(SurfNum).Class != SurfaceClass::Wall) continue; + // assign major surfaces + for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { + if (Surface(SurfNum).Class != SurfaceClass::Wall) continue; - if (Surface(SurfNum).Width == majorW) { - if (Surf1 == 0) { - Surf1 = SurfNum; - } else { - Surf2 = SurfNum; + if (Surface(SurfNum).Width == majorW) { + if (Surf1 == 0) { + Surf1 = SurfNum; + } else { + Surf2 = SurfNum; - break; // both major surfaces are now assigned + break; // both major surfaces are now assigned + } } } } @@ -3653,7 +3664,7 @@ void CalcTrombeWallIntConvCoeff(EnergyPlusData &state, Gr = (g * beta * std::abs(Tsi - Tso) * pow_3(gapW)) / pow_2(v); // curve fit for v = v(T)? - CalcNusselt(state, SurfNum, asp, Tso, Tsi, Gr, Pr, Nu); // curve fit for Pr = Pr(T)? + CalcNusselt(state, Surf2, asp, Tso, Tsi, Gr, Pr, Nu); // curve fit for Pr = Pr(T)? HConvNet = (k / gapW) * Nu; // curve fit for k = k(T)? @@ -3662,21 +3673,25 @@ void CalcTrombeWallIntConvCoeff(EnergyPlusData &state, } // Assign convection coefficients - for (SurfNum = Zone(ZoneNum).HTSurfaceFirst; SurfNum <= Zone(ZoneNum).HTSurfaceLast; ++SurfNum) { - // Use ASHRAESimple correlation to give values for all the minor surfaces - CalcASHRAESimpleIntConvCoeff(state, SurfNum, SurfaceTemperatures(SurfNum), state.dataHeatBalFanSys->MAT(ZoneNum)); - - // assign the convection coefficent to the major surfaces and any subsurfaces on them - if ((Surface(SurfNum).BaseSurf == Surf1) || (Surface(SurfNum).BaseSurf == Surf2)) { - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { - ShowFatalError(state, "Trombe wall convection model not applicable for foundation surface =" + Surface(SurfNum).Name); + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { + // Use ASHRAESimple correlation to give values for all the minor surfaces + CalcASHRAESimpleIntConvCoeff( + state, SurfNum, SurfaceTemperatures(SurfNum), state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT); + + // assign the convection coefficent to the major surfaces and any subsurfaces on them + if ((Surface(SurfNum).BaseSurf == Surf1) || (Surface(SurfNum).BaseSurf == Surf2)) { + if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + ShowFatalError(state, "Trombe wall convection model not applicable for foundation surface =" + Surface(SurfNum).Name); + } + state.dataHeatBalSurf->SurfHConvInt(SurfNum) = 2.0 * HConvNet; } - state.dataHeatBalSurf->SurfHConvInt(SurfNum) = 2.0 * HConvNet; - } - // Establish some lower limit to avoid a zero convection coefficient (and potential divide by zero problems) - if (state.dataHeatBalSurf->SurfHConvInt(SurfNum) < state.dataHeatBal->LowHConvLimit) - state.dataHeatBalSurf->SurfHConvInt(SurfNum) = state.dataHeatBal->LowHConvLimit; + // Establish some lower limit to avoid a zero convection coefficient (and potential divide by zero problems) + if (state.dataHeatBalSurf->SurfHConvInt(SurfNum) < state.dataHeatBal->LowHConvLimit) + state.dataHeatBalSurf->SurfHConvInt(SurfNum) = state.dataHeatBal->LowHConvLimit; + } } } @@ -4049,7 +4064,7 @@ void CalcISO15099WindowIntConvCoeff(EnergyPlusData &state, // Get humidity ratio Real64 AirHumRat; if (Surface(SurfNum).Zone > 0) { - AirHumRat = state.dataHeatBalFanSys->ZoneAirHumRatAvg(Surface(SurfNum).Zone); + AirHumRat = state.dataZoneTempPredictorCorrector->zoneHeatBalance(Surface(SurfNum).Zone).ZoneAirHumRatAvg; } else { AirHumRat = state.dataEnvrn->OutHumRat; } @@ -4250,61 +4265,69 @@ void SetupAdaptiveConvectionStaticMetaData(EnergyPlusData &state) } else { thisWWR = -999.0; // throw error? } - // first pass thru this zones surfaces to gather data - for (int SurfLoop = Zone(ZoneLoop).HTSurfaceFirst; SurfLoop <= Zone(ZoneLoop).HTSurfaceLast; ++SurfLoop) { - // first catch exterior walls and do summations - if ((Surface(SurfLoop).ExtBoundCond == ExternalEnvironment) && (Surface(SurfLoop).Class == SurfaceClass::Wall)) { - PerimExtLengthSum += Surface(SurfLoop).Width; - ++ExtWallCount; - } - if ((Surface(SurfLoop).ExtBoundCond == ExternalEnvironment) && - ((Surface(SurfLoop).Class == SurfaceClass::Window) || (Surface(SurfLoop).Class == SurfaceClass::GlassDoor))) { - ++ExtWindowCount; + for (int spaceNum : state.dataHeatBal->Zone(ZoneLoop).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + // first pass thru this zones surfaces to gather data + for (int SurfLoop = thisSpace.HTSurfaceFirst; SurfLoop <= thisSpace.HTSurfaceLast; ++SurfLoop) { + // first catch exterior walls and do summations + if ((Surface(SurfLoop).ExtBoundCond == ExternalEnvironment) && (Surface(SurfLoop).Class == SurfaceClass::Wall)) { + PerimExtLengthSum += Surface(SurfLoop).Width; + ++ExtWallCount; + } + if ((Surface(SurfLoop).ExtBoundCond == ExternalEnvironment) && + ((Surface(SurfLoop).Class == SurfaceClass::Window) || (Surface(SurfLoop).Class == SurfaceClass::GlassDoor))) { + ++ExtWindowCount; + } } } - - // second pass thru zone surfs to fill data - for (int SurfLoop = Zone(ZoneLoop).HTSurfaceFirst; SurfLoop <= Zone(ZoneLoop).HTSurfaceLast; ++SurfLoop) { - // now fill values - state.dataSurface->SurfIntConvZoneWallHeight(SurfLoop) = Zone(ZoneLoop).CeilingHeight; - state.dataSurface->SurfIntConvZonePerimLength(SurfLoop) = PerimExtLengthSum; - state.dataSurface->SurfIntConvZoneHorizHydrDiam(SurfLoop) = thisZoneHorizHydralicDiameter; - state.dataSurface->SurfIntConvWindowWallRatio(SurfLoop) = thisWWR; - } // 2nd pass over surfaces. + for (int spaceNum : state.dataHeatBal->Zone(ZoneLoop).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + // second pass thru zone surfs to fill data + for (int SurfLoop = thisSpace.HTSurfaceFirst; SurfLoop <= thisSpace.HTSurfaceLast; ++SurfLoop) { + // now fill values + state.dataSurface->SurfIntConvZoneWallHeight(SurfLoop) = Zone(ZoneLoop).CeilingHeight; + state.dataSurface->SurfIntConvZonePerimLength(SurfLoop) = PerimExtLengthSum; + state.dataSurface->SurfIntConvZoneHorizHydrDiam(SurfLoop) = thisZoneHorizHydralicDiameter; + state.dataSurface->SurfIntConvWindowWallRatio(SurfLoop) = thisWWR; + } // 2nd pass over surfaces. + } // third pass for window locations if ((ExtWindowCount > 0) && (ExtWallCount > 0)) { - for (int SurfLoop = Zone(ZoneLoop).HTSurfaceFirst; SurfLoop <= Zone(ZoneLoop).HTSurfaceLast; ++SurfLoop) { - if ((Surface(SurfLoop).ExtBoundCond == ExternalEnvironment) && - ((Surface(SurfLoop).Class == SurfaceClass::Window) || (Surface(SurfLoop).Class == SurfaceClass::GlassDoor))) { - if (state.dataSurface->SurfIntConvWindowWallRatio(SurfLoop) < 0.5) { - if (Surface(SurfLoop).Centroid.z < Zone(ZoneLoop).Centroid.z) { - state.dataSurface->SurfIntConvWindowLocation(SurfLoop) = ConvectionConstants::InConvWinLoc::LowerPartOfExteriorWall; + for (int spaceNum : state.dataHeatBal->Zone(ZoneLoop).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int SurfLoop = thisSpace.HTSurfaceFirst; SurfLoop <= thisSpace.HTSurfaceLast; ++SurfLoop) { + if ((Surface(SurfLoop).ExtBoundCond == ExternalEnvironment) && + ((Surface(SurfLoop).Class == SurfaceClass::Window) || (Surface(SurfLoop).Class == SurfaceClass::GlassDoor))) { + if (state.dataSurface->SurfIntConvWindowWallRatio(SurfLoop) < 0.5) { + if (Surface(SurfLoop).Centroid.z < Zone(ZoneLoop).Centroid.z) { + state.dataSurface->SurfIntConvWindowLocation(SurfLoop) = ConvectionConstants::InConvWinLoc::LowerPartOfExteriorWall; + } else { + state.dataSurface->SurfIntConvWindowLocation(SurfLoop) = ConvectionConstants::InConvWinLoc::UpperPartOfExteriorWall; + } } else { - state.dataSurface->SurfIntConvWindowLocation(SurfLoop) = ConvectionConstants::InConvWinLoc::UpperPartOfExteriorWall; + state.dataSurface->SurfIntConvWindowLocation(SurfLoop) = ConvectionConstants::InConvWinLoc::LargePartOfExteriorWall; + } + if ((Surface(Surface(SurfLoop).BaseSurf).ExtBoundCond == ExternalEnvironment) && + (Surface(Surface(SurfLoop).BaseSurf).Class == SurfaceClass::Wall)) { + if (Surface(Surface(SurfLoop).BaseSurf).Centroid.z < Surface(SurfLoop).Centroid.z) { + state.dataSurface->SurfIntConvWindowLocation(Surface(SurfLoop).BaseSurf) = + ConvectionConstants::InConvWinLoc::WindowAboveThis; + } else { + state.dataSurface->SurfIntConvWindowLocation(Surface(SurfLoop).BaseSurf) = + ConvectionConstants::InConvWinLoc::WindowBelowThis; + } } - } else { - state.dataSurface->SurfIntConvWindowLocation(SurfLoop) = ConvectionConstants::InConvWinLoc::LargePartOfExteriorWall; } - if ((Surface(Surface(SurfLoop).BaseSurf).ExtBoundCond == ExternalEnvironment) && - (Surface(Surface(SurfLoop).BaseSurf).Class == SurfaceClass::Wall)) { - if (Surface(Surface(SurfLoop).BaseSurf).Centroid.z < Surface(SurfLoop).Centroid.z) { - state.dataSurface->SurfIntConvWindowLocation(Surface(SurfLoop).BaseSurf) = - ConvectionConstants::InConvWinLoc::WindowAboveThis; + if ((Surface(SurfLoop).ExtBoundCond == ExternalEnvironment) && (Surface(SurfLoop).Class == SurfaceClass::Wall) && + (state.dataSurface->SurfIntConvWindowLocation(SurfLoop) == ConvectionConstants::InConvWinLoc::NotSet)) { + if (Surface(SurfLoop).Centroid.z < Zone(ZoneLoop).Centroid.z) { + state.dataSurface->SurfIntConvWindowLocation(SurfLoop) = ConvectionConstants::InConvWinLoc::WindowAboveThis; } else { - state.dataSurface->SurfIntConvWindowLocation(Surface(SurfLoop).BaseSurf) = - ConvectionConstants::InConvWinLoc::WindowBelowThis; + state.dataSurface->SurfIntConvWindowLocation(SurfLoop) = ConvectionConstants::InConvWinLoc::WindowBelowThis; } } } - if ((Surface(SurfLoop).ExtBoundCond == ExternalEnvironment) && (Surface(SurfLoop).Class == SurfaceClass::Wall) && - (state.dataSurface->SurfIntConvWindowLocation(SurfLoop) == ConvectionConstants::InConvWinLoc::NotSet)) { - if (Surface(SurfLoop).Centroid.z < Zone(ZoneLoop).Centroid.z) { - state.dataSurface->SurfIntConvWindowLocation(SurfLoop) = ConvectionConstants::InConvWinLoc::WindowAboveThis; - } else { - state.dataSurface->SurfIntConvWindowLocation(SurfLoop) = ConvectionConstants::InConvWinLoc::WindowBelowThis; - } - } } // third pass over surfaces } } // loop over zones for inside face parameters @@ -4700,14 +4723,9 @@ void SetupAdaptiveConvectionRadiantSurfaceData(EnergyPlusData &state) // Using/Aliasing using namespace DataZoneEquipment; - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int ZoneLoop; - int SurfLoop; - - auto &Zone(state.dataHeatBal->Zone); auto &Surface(state.dataSurface->Surface); - for (ZoneLoop = 1; ZoneLoop <= state.dataGlobal->NumOfZones; ++ZoneLoop) { + for (int ZoneLoop = 1; ZoneLoop <= state.dataGlobal->NumOfZones; ++ZoneLoop) { state.dataConvectionCoefficient->ActiveWallCount = 0; state.dataConvectionCoefficient->ActiveWallArea = 0.0; state.dataConvectionCoefficient->ActiveCeilingCount = 0; @@ -4715,17 +4733,20 @@ void SetupAdaptiveConvectionRadiantSurfaceData(EnergyPlusData &state) state.dataConvectionCoefficient->ActiveFloorCount = 0; state.dataConvectionCoefficient->ActiveFloorArea = 0.0; - for (SurfLoop = Zone(ZoneLoop).HTSurfaceFirst; SurfLoop <= Zone(ZoneLoop).HTSurfaceLast; ++SurfLoop) { - if (!state.dataSurface->SurfIntConvSurfHasActiveInIt(SurfLoop)) continue; - if (Surface(SurfLoop).Class == SurfaceClass::Wall || Surface(SurfLoop).Class == SurfaceClass::Door) { - ++state.dataConvectionCoefficient->ActiveWallCount; - state.dataConvectionCoefficient->ActiveWallArea += Surface(SurfLoop).Area; - } else if (Surface(SurfLoop).Class == SurfaceClass::Roof) { - ++state.dataConvectionCoefficient->ActiveCeilingCount; - state.dataConvectionCoefficient->ActiveCeilingArea += Surface(SurfLoop).Area; - } else if (Surface(SurfLoop).Class == SurfaceClass::Floor) { - ++state.dataConvectionCoefficient->ActiveFloorCount; - state.dataConvectionCoefficient->ActiveFloorArea += Surface(SurfLoop).Area; + for (int spaceNum : state.dataHeatBal->Zone(ZoneLoop).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int SurfLoop = thisSpace.HTSurfaceFirst; SurfLoop <= thisSpace.HTSurfaceLast; ++SurfLoop) { + if (!state.dataSurface->SurfIntConvSurfHasActiveInIt(SurfLoop)) continue; + if (Surface(SurfLoop).Class == SurfaceClass::Wall || Surface(SurfLoop).Class == SurfaceClass::Door) { + ++state.dataConvectionCoefficient->ActiveWallCount; + state.dataConvectionCoefficient->ActiveWallArea += Surface(SurfLoop).Area; + } else if (Surface(SurfLoop).Class == SurfaceClass::Roof) { + ++state.dataConvectionCoefficient->ActiveCeilingCount; + state.dataConvectionCoefficient->ActiveCeilingArea += Surface(SurfLoop).Area; + } else if (Surface(SurfLoop).Class == SurfaceClass::Floor) { + ++state.dataConvectionCoefficient->ActiveFloorCount; + state.dataConvectionCoefficient->ActiveFloorArea += Surface(SurfLoop).Area; + } } } // surface loop @@ -4808,8 +4829,6 @@ void EvaluateIntHcModels(EnergyPlusData &state, // SUBROUTINE INFORMATION: // AUTHOR Brent Griffith // DATE WRITTEN Aug 2010 - // MODIFIED na - // RE-ENGINEERED na // PURPOSE OF THIS SUBROUTINE: // central case statement for calling inside convection models @@ -4819,16 +4838,12 @@ void EvaluateIntHcModels(EnergyPlusData &state, // preparation of argument values for the function calls is contained in each Case block (repeats) // - also updates the reference air temperature type for use in the surface heat balance calcs - // Using/Aliasing - - auto &Zone(state.dataHeatBal->Zone); - auto &Surface(state.dataSurface->Surface); - Real64 tmpHc = 0.0; - int const ZoneNum = Surface(SurfNum).Zone; - Real64 &Tsurface = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum); - Real64 &Tzone = state.dataHeatBalFanSys->MAT(ZoneNum); + auto const &thisSurface = state.dataSurface->Surface(SurfNum); + int const ZoneNum = thisSurface.Zone; + Real64 const Tsurface = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum); + Real64 const Tzone = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; auto &HnFn = state.dataSurfaceGeometry->kivaManager.surfaceConvMap[SurfNum].in; // now call appropriate function to calculate Hc @@ -4838,7 +4853,7 @@ void EvaluateIntHcModels(EnergyPlusData &state, CalcUserDefinedInsideHcModel(state, SurfNum, state.dataSurface->SurfIntConvHcUserCurveIndex(SurfNum), tmpHc); break; case ConvectionConstants::HcInt_ASHRAEVerticalWall: - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { HnFn = [](double Tsurf, double Tamb, double, double, double) -> double { return CalcASHRAEVerticalWall(Tsurf - Tamb); }; } else { tmpHc = CalcASHRAEVerticalWall((Tsurface - Tzone)); @@ -4846,93 +4861,93 @@ void EvaluateIntHcModels(EnergyPlusData &state, state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; break; case ConvectionConstants::HcInt_WaltonUnstableHorizontalOrTilt: - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { HnFn = [](double Tsurf, double Tamb, double, double, double cosTilt) -> double { return CalcWaltonUnstableHorizontalOrTilt(Tsurf - Tamb, cosTilt); }; } else { - tmpHc = CalcWaltonUnstableHorizontalOrTilt((Tsurface - Tzone), Surface(SurfNum).CosTilt); // TODO verify CosTilt in vs out + tmpHc = CalcWaltonUnstableHorizontalOrTilt((Tsurface - Tzone), thisSurface.CosTilt); // TODO verify CosTilt in vs out } state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; break; case ConvectionConstants::HcInt_WaltonStableHorizontalOrTilt: - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { HnFn = [](double Tsurf, double Tamb, double, double, double cosTilt) -> double { return CalcWaltonStableHorizontalOrTilt(Tsurf - Tamb, cosTilt); }; } else { - tmpHc = CalcWaltonStableHorizontalOrTilt((Tsurface - Tzone), Surface(SurfNum).CosTilt); // TODO verify CosTilt in vs out + tmpHc = CalcWaltonStableHorizontalOrTilt((Tsurface - Tzone), thisSurface.CosTilt); // TODO verify CosTilt in vs out } state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; break; case ConvectionConstants::HcInt_FisherPedersenCeilDiffuserFloor: { Real64 AirChangeRate = CalcCeilingDiffuserACH(state, ZoneNum); - Real64 AirHumRat = state.dataHeatBalFanSys->ZoneAirHumRatAvg(ZoneNum); - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + Real64 AirHumRat = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZoneAirHumRatAvg; + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { HnFn = [=, &state](double Tsurf, double Tamb, double, double, double cosTilt) -> double { - return CalcFisherPedersenCeilDiffuserFloor(state, AirChangeRate, Tsurf, Tamb, cosTilt, AirHumRat, Surface(SurfNum).Height); + return CalcFisherPedersenCeilDiffuserFloor(state, AirChangeRate, Tsurf, Tamb, cosTilt, AirHumRat, thisSurface.Height); }; } else { tmpHc = CalcFisherPedersenCeilDiffuserFloor(state, AirChangeRate, Tsurface, Tzone, - Surface(SurfNum).CosTilt, + thisSurface.CosTilt, AirHumRat, - Surface(SurfNum).Height, - state.dataConstruction->Construct(Surface(SurfNum).Construction).TypeIsWindow); + thisSurface.Height, + state.dataConstruction->Construct(thisSurface.Construction).TypeIsWindow); } state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; break; } case ConvectionConstants::HcInt_FisherPedersenCeilDiffuserCeiling: { Real64 AirChangeRate = CalcCeilingDiffuserACH(state, ZoneNum); - Real64 AirHumRat = state.dataHeatBalFanSys->ZoneAirHumRatAvg(ZoneNum); - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + Real64 AirHumRat = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZoneAirHumRatAvg; + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { HnFn = [=, &state](double Tsurf, double Tamb, double, double, double cosTilt) -> double { - return CalcFisherPedersenCeilDiffuserCeiling(state, AirChangeRate, Tsurf, Tamb, cosTilt, AirHumRat, Surface(SurfNum).Height); + return CalcFisherPedersenCeilDiffuserCeiling(state, AirChangeRate, Tsurf, Tamb, cosTilt, AirHumRat, thisSurface.Height); }; } else { tmpHc = CalcFisherPedersenCeilDiffuserCeiling(state, AirChangeRate, Tsurface, Tzone, - Surface(SurfNum).CosTilt, + thisSurface.CosTilt, AirHumRat, - Surface(SurfNum).Height, - state.dataConstruction->Construct(Surface(SurfNum).Construction).TypeIsWindow); + thisSurface.Height, + state.dataConstruction->Construct(thisSurface.Construction).TypeIsWindow); } state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; break; } case ConvectionConstants::HcInt_FisherPedersenCeilDiffuserWalls: { Real64 AirChangeRate = CalcCeilingDiffuserACH(state, ZoneNum); - Real64 AirHumRat = state.dataHeatBalFanSys->ZoneAirHumRatAvg(ZoneNum); - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + Real64 AirHumRat = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZoneAirHumRatAvg; + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { HnFn = [=, &state](double Tsurf, double Tamb, double, double, double cosTilt) -> double { - return CalcFisherPedersenCeilDiffuserWalls(state, AirChangeRate, Tsurf, Tamb, cosTilt, AirHumRat, Surface(SurfNum).Height); + return CalcFisherPedersenCeilDiffuserWalls(state, AirChangeRate, Tsurf, Tamb, cosTilt, AirHumRat, thisSurface.Height); }; } else { tmpHc = CalcFisherPedersenCeilDiffuserWalls(state, AirChangeRate, Tsurface, Tzone, - Surface(SurfNum).CosTilt, + thisSurface.CosTilt, AirHumRat, - Surface(SurfNum).Height, - state.dataConstruction->Construct(Surface(SurfNum).Construction).TypeIsWindow); + thisSurface.Height, + state.dataConstruction->Construct(thisSurface.Construction).TypeIsWindow); } - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { HnFn = [=](double, double, double, double, double) -> double { return tmpHc; }; } state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; break; } case ConvectionConstants::HcInt_AlamdariHammondStableHorizontal: - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { Real64 HorizHydrDiam = state.dataSurface->SurfIntConvZoneHorizHydrDiam(SurfNum); HnFn = [=](double Tsurf, double Tamb, double, double, double) -> double { return CalcAlamdariHammondStableHorizontal(Tsurf - Tamb, HorizHydrDiam); @@ -4943,7 +4958,7 @@ void EvaluateIntHcModels(EnergyPlusData &state, state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; break; case ConvectionConstants::HcInt_AlamdariHammondVerticalWall: - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { Real64 WallHeight = state.dataSurface->SurfIntConvZoneWallHeight(SurfNum); HnFn = [=](double Tsurf, double Tamb, double, double, double) -> double { return CalcAlamdariHammondVerticalWall(Tsurf - Tamb, WallHeight); @@ -4954,7 +4969,7 @@ void EvaluateIntHcModels(EnergyPlusData &state, state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; break; case ConvectionConstants::HcInt_AlamdariHammondUnstableHorizontal: - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { Real64 HorizHydrDiam = state.dataSurface->SurfIntConvZoneHorizHydrDiam(SurfNum); HnFn = [=](double Tsurf, double Tamb, double, double, double) -> double { return CalcAlamdariHammondStableHorizontal(Tsurf - Tamb, HorizHydrDiam); @@ -4966,7 +4981,7 @@ void EvaluateIntHcModels(EnergyPlusData &state, state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; break; case ConvectionConstants::HcInt_KhalifaEq3WallAwayFromHeat: - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { HnFn = [=](double Tsurf, double Tamb, double, double, double) -> double { return CalcKhalifaEq3WallAwayFromHeat(Tsurf - Tamb); }; } else { tmpHc = CalcKhalifaEq3WallAwayFromHeat((Tsurface - Tzone)); @@ -4974,7 +4989,7 @@ void EvaluateIntHcModels(EnergyPlusData &state, state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; break; case ConvectionConstants::HcInt_KhalifaEq4CeilingAwayFromHeat: - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { HnFn = [=](double Tsurf, double Tamb, double, double, double) -> double { return CalcKhalifaEq4CeilingAwayFromHeat(Tsurf - Tamb); }; } else { tmpHc = CalcKhalifaEq4CeilingAwayFromHeat((Tsurface - Tzone)); @@ -4982,7 +4997,7 @@ void EvaluateIntHcModels(EnergyPlusData &state, state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; break; case ConvectionConstants::HcInt_KhalifaEq5WallNearHeat: - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { HnFn = [=](double Tsurf, double Tamb, double, double, double) -> double { return CalcKhalifaEq5WallsNearHeat(Tsurf - Tamb); }; } else { tmpHc = CalcKhalifaEq5WallsNearHeat((Tsurface - Tzone)); @@ -4990,7 +5005,7 @@ void EvaluateIntHcModels(EnergyPlusData &state, state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; break; case ConvectionConstants::HcInt_KhalifaEq6NonHeatedWalls: - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { HnFn = [=](double Tsurf, double Tamb, double, double, double) -> double { return CalcKhalifaEq6NonHeatedWalls(Tsurf - Tamb); }; } else { tmpHc = CalcKhalifaEq6NonHeatedWalls((Tsurface - Tzone)); @@ -4998,7 +5013,7 @@ void EvaluateIntHcModels(EnergyPlusData &state, state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; break; case ConvectionConstants::HcInt_KhalifaEq7Ceiling: - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { HnFn = [=](double Tsurf, double Tamb, double, double, double) -> double { return CalcKhalifaEq7Ceiling(Tsurf - Tamb); }; } else { tmpHc = CalcKhalifaEq7Ceiling((Tsurface - Tzone)); @@ -5006,7 +5021,7 @@ void EvaluateIntHcModels(EnergyPlusData &state, state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; break; case ConvectionConstants::HcInt_AwbiHattonHeatedFloor: - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { Real64 HorizHydrDiam = state.dataSurface->SurfIntConvZoneHorizHydrDiam(SurfNum); HnFn = [=](double Tsurf, double Tamb, double, double, double) -> double { return CalcAwbiHattonHeatedFloor(Tsurf - Tamb, HorizHydrDiam); @@ -5017,7 +5032,7 @@ void EvaluateIntHcModels(EnergyPlusData &state, state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; break; case ConvectionConstants::HcInt_AwbiHattonHeatedWall: - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { Real64 HorizHydrDiam = state.dataSurface->SurfIntConvZoneHorizHydrDiam(SurfNum); HnFn = [=](double Tsurf, double Tamb, double, double, double) -> double { return CalcAwbiHattonHeatedWall(Tsurf - Tamb, HorizHydrDiam); }; } else { @@ -5026,7 +5041,7 @@ void EvaluateIntHcModels(EnergyPlusData &state, state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; break; case ConvectionConstants::HcInt_BeausoleilMorrisonMixedAssistingWall: - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { HnFn = [=, &state](double Tsurf, double Tamb, double, double, double) -> double { return CalcBeausoleilMorrisonMixedAssistedWall(Tsurf - Tamb, state.dataSurface->SurfIntConvZoneWallHeight(SurfNum), @@ -5041,7 +5056,7 @@ void EvaluateIntHcModels(EnergyPlusData &state, state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; break; case ConvectionConstants::HcInt_BeausoleilMorrisonMixedOppossingWall: - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { HnFn = [=, &state](double Tsurf, double Tamb, double, double, double) -> double { return CalcBeausoleilMorrisonMixedOpposingWall(Tsurf - Tamb, state.dataSurface->SurfIntConvZoneWallHeight(SurfNum), @@ -5056,7 +5071,7 @@ void EvaluateIntHcModels(EnergyPlusData &state, state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; break; case ConvectionConstants::HcInt_BeausoleilMorrisonMixedStableCeiling: - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { HnFn = [=, &state](double Tsurf, double Tamb, double, double, double) -> double { return CalcBeausoleilMorrisonMixedStableCeiling(Tsurf - Tamb, state.dataSurface->SurfIntConvZoneHorizHydrDiam(SurfNum), @@ -5071,7 +5086,7 @@ void EvaluateIntHcModels(EnergyPlusData &state, state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; break; case ConvectionConstants::HcInt_BeausoleilMorrisonMixedUnstableCeiling: - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { HnFn = [=, &state](double Tsurf, double Tamb, double, double, double) -> double { return CalcBeausoleilMorrisonMixedUnstableCeiling(Tsurf - Tamb, state.dataSurface->SurfIntConvZoneHorizHydrDiam(SurfNum), @@ -5086,7 +5101,7 @@ void EvaluateIntHcModels(EnergyPlusData &state, state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; break; case ConvectionConstants::HcInt_BeausoleilMorrisonMixedStableFloor: - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { HnFn = [=, &state](double Tsurf, double Tamb, double, double, double) -> double { return CalcBeausoleilMorrisonMixedStableFloor(Tsurf - Tamb, state.dataSurface->SurfIntConvZoneHorizHydrDiam(SurfNum), @@ -5101,7 +5116,7 @@ void EvaluateIntHcModels(EnergyPlusData &state, state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; break; case ConvectionConstants::HcInt_BeausoleilMorrisonMixedUnstableFloor: - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { HnFn = [=, &state](double Tsurf, double Tamb, double, double, double) -> double { return CalcBeausoleilMorrisonMixedUnstableFloor(Tsurf - Tamb, state.dataSurface->SurfIntConvZoneHorizHydrDiam(SurfNum), @@ -5116,7 +5131,7 @@ void EvaluateIntHcModels(EnergyPlusData &state, state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; break; case ConvectionConstants::HcInt_FohannoPolidoriVerticalWall: - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { Real64 QdotConvection = -state.dataHeatBalSurf->SurfQdotConvInPerArea(SurfNum); Real64 WallHeight = state.dataSurface->SurfIntConvZoneWallHeight(SurfNum); HnFn = [=](double Tsurf, double Tamb, double, double, double) -> double { @@ -5136,7 +5151,7 @@ void EvaluateIntHcModels(EnergyPlusData &state, state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; break; case ConvectionConstants::HcInt_KaradagChilledCeiling: - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { HnFn = [=](double Tsurf, double Tamb, double, double, double) -> double { return CalcKaradagChilledCeiling(Tsurf - Tamb); }; } else { tmpHc = CalcKaradagChilledCeiling((Tsurface - Tzone)); @@ -5154,11 +5169,10 @@ void EvaluateIntHcModels(EnergyPlusData &state, state.dataSurface->SurfIntConvWindowWallRatio(SurfNum), state.dataSurface->SurfIntConvWindowLocation(SurfNum), ZoneNum); - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { HnFn = [=](double, double, double, double, double) -> double { return tmpHc; }; } - int ZoneNode = Zone(ZoneNum).SystemZoneNodeNumber; - if (ZoneNode > 0) { + if (state.dataHeatBal->Zone(ZoneNum).SystemZoneNodeNumber > 0) { state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneSupplyAirTemp; } else { state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; @@ -5168,11 +5182,10 @@ void EvaluateIntHcModels(EnergyPlusData &state, case ConvectionConstants::HcInt_GoldsteinNovoselacCeilingDiffuserWalls: { tmpHc = CalcGoldsteinNovoselacCeilingDiffuserWall( state, state.dataSurface->SurfIntConvZonePerimLength(SurfNum), state.dataSurface->SurfIntConvWindowLocation(SurfNum), ZoneNum); - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { HnFn = [=](double, double, double, double, double) -> double { return tmpHc; }; } - int ZoneNode = Zone(ZoneNum).SystemZoneNodeNumber; - if (ZoneNode > 0) { + if (state.dataHeatBal->Zone(ZoneNum).SystemZoneNodeNumber > 0) { state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneSupplyAirTemp; } else { state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; @@ -5181,11 +5194,10 @@ void EvaluateIntHcModels(EnergyPlusData &state, } case ConvectionConstants::HcInt_GoldsteinNovoselacCeilingDiffuserFloor: { tmpHc = CalcGoldsteinNovoselacCeilingDiffuserFloor(state.dataSurface->SurfIntConvZonePerimLength(SurfNum), ZoneNum); - if (Surface(SurfNum).ExtBoundCond == DataSurfaces::KivaFoundation) { + if (thisSurface.ExtBoundCond == DataSurfaces::KivaFoundation) { HnFn = [=](double, double, double, double, double) -> double { return tmpHc; }; } - int ZoneNode = Zone(ZoneNum).SystemZoneNodeNumber; - if (ZoneNode > 0) { + if (state.dataHeatBal->Zone(ZoneNum).SystemZoneNodeNumber > 0) { state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneSupplyAirTemp; } else { state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; @@ -5693,7 +5705,6 @@ void DynamicIntConvSurfaceClassification(EnergyPlusData &state, int const SurfNu Real64 Ri(0.0); // Richardson Number, Gr/Re**2 for determining mixed regime Real64 AirDensity(0.0); // temporary zone air density Real64 DeltaTemp(0.0); // temporary temperature difference (Tsurf - Tair) - int SurfLoop; // local for separate looping across surfaces in the zone that has SurfNum auto &Zone(state.dataHeatBal->Zone); auto &Surface(state.dataSurface->Surface); @@ -5823,71 +5834,83 @@ void DynamicIntConvSurfaceClassification(EnergyPlusData &state, int const SurfNu case DataZoneEquipment::ZoneEquip::VentilatedSlab: case DataZoneEquipment::ZoneEquip::LoTempRadiant: if (state.dataZoneEquip->ZoneEquipConfig(ZoneNum).InFloorActiveElement) { - for (SurfLoop = Zone(ZoneNum).HTSurfaceFirst; SurfLoop <= Zone(ZoneNum).HTSurfaceLast; ++SurfLoop) { - if (!state.dataSurface->SurfIntConvSurfHasActiveInIt(SurfLoop)) continue; - if (Surface(SurfLoop).Class == SurfaceClass::Floor) { - DeltaTemp = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfLoop) - state.dataHeatBalFanSys->MAT(ZoneNum); - if (DeltaTemp > ActiveDelTempThreshold) { // assume heating with floor - // system ON is not enough because floor surfaces can continue to heat because of thermal capacity - EquipOnCount = min(EquipOnCount + 1, MaxZoneEquipmentIdx); - FlowRegimeStack[EquipOnCount] = InConvFlowRegime::A1; - HeatingPriorityStack[EquipOnCount] = - state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ZoneNum).EquipListIndex) - .HeatingPriority(EquipNum); - CoolingPriorityStack[EquipOnCount] = - state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ZoneNum).EquipListIndex) - .CoolingPriority(EquipNum); - break; + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int SurfLoop = thisSpace.HTSurfaceFirst; SurfLoop <= thisSpace.HTSurfaceLast; ++SurfLoop) { + if (!state.dataSurface->SurfIntConvSurfHasActiveInIt(SurfLoop)) continue; + if (Surface(SurfLoop).Class == SurfaceClass::Floor) { + DeltaTemp = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfLoop) - + state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; + if (DeltaTemp > ActiveDelTempThreshold) { // assume heating with floor + // system ON is not enough because floor surfaces can continue to heat because of thermal capacity + EquipOnCount = min(EquipOnCount + 1, MaxZoneEquipmentIdx); + FlowRegimeStack[EquipOnCount] = InConvFlowRegime::A1; + HeatingPriorityStack[EquipOnCount] = + state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ZoneNum).EquipListIndex) + .HeatingPriority(EquipNum); + CoolingPriorityStack[EquipOnCount] = + state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ZoneNum).EquipListIndex) + .CoolingPriority(EquipNum); + break; + } } } } } if (state.dataZoneEquip->ZoneEquipConfig(ZoneNum).InCeilingActiveElement) { - for (SurfLoop = Zone(ZoneNum).HTSurfaceFirst; SurfLoop <= Zone(ZoneNum).HTSurfaceLast; ++SurfLoop) { - if (!state.dataSurface->SurfIntConvSurfHasActiveInIt(SurfLoop)) continue; - if (Surface(SurfLoop).Class == SurfaceClass::Roof) { - DeltaTemp = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfLoop) - state.dataHeatBalFanSys->MAT(ZoneNum); - if (DeltaTemp < ActiveDelTempThreshold) { // assume cooling with ceiling - // system ON is not enough because surfaces can continue to cool because of thermal capacity - EquipOnCount = min(EquipOnCount + 1, MaxZoneEquipmentIdx); - FlowRegimeStack[EquipOnCount] = InConvFlowRegime::A1; - HeatingPriorityStack[EquipOnCount] = - state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ZoneNum).EquipListIndex) - .HeatingPriority(EquipNum); - CoolingPriorityStack[EquipOnCount] = - state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ZoneNum).EquipListIndex) - .CoolingPriority(EquipNum); - break; + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int SurfLoop = thisSpace.HTSurfaceFirst; SurfLoop <= thisSpace.HTSurfaceLast; ++SurfLoop) { + if (!state.dataSurface->SurfIntConvSurfHasActiveInIt(SurfLoop)) continue; + if (Surface(SurfLoop).Class == SurfaceClass::Roof) { + DeltaTemp = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfLoop) - + state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; + if (DeltaTemp < ActiveDelTempThreshold) { // assume cooling with ceiling + // system ON is not enough because surfaces can continue to cool because of thermal capacity + EquipOnCount = min(EquipOnCount + 1, MaxZoneEquipmentIdx); + FlowRegimeStack[EquipOnCount] = InConvFlowRegime::A1; + HeatingPriorityStack[EquipOnCount] = + state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ZoneNum).EquipListIndex) + .HeatingPriority(EquipNum); + CoolingPriorityStack[EquipOnCount] = + state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ZoneNum).EquipListIndex) + .CoolingPriority(EquipNum); + break; + } } } } } if (state.dataZoneEquip->ZoneEquipConfig(ZoneNum).InWallActiveElement) { - for (SurfLoop = Zone(ZoneNum).HTSurfaceFirst; SurfLoop <= Zone(ZoneNum).HTSurfaceLast; ++SurfLoop) { - if (!state.dataSurface->SurfIntConvSurfHasActiveInIt(SurfLoop)) continue; - if (Surface(SurfLoop).Class == SurfaceClass::Wall || Surface(SurfLoop).Class == SurfaceClass::Door) { - DeltaTemp = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfLoop) - state.dataHeatBalFanSys->MAT(ZoneNum); - if (DeltaTemp > ActiveDelTempThreshold) { // assume heating with wall panel - // system ON is not enough because surfaces can continue to heat because of thermal capacity - EquipOnCount = min(EquipOnCount + 1, MaxZoneEquipmentIdx); - FlowRegimeStack[EquipOnCount] = InConvFlowRegime::A2; - HeatingPriorityStack[EquipOnCount] = - state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ZoneNum).EquipListIndex) - .HeatingPriority(EquipNum); - CoolingPriorityStack[EquipOnCount] = - state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ZoneNum).EquipListIndex) - .CoolingPriority(EquipNum); - } else { // not heating, no special models wall cooling so use simple buoyancy - EquipOnCount = min(EquipOnCount + 1, MaxZoneEquipmentIdx); - FlowRegimeStack[EquipOnCount] = InConvFlowRegime::A3; - HeatingPriorityStack[EquipOnCount] = - state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ZoneNum).EquipListIndex) - .HeatingPriority(EquipNum); - CoolingPriorityStack[EquipOnCount] = - state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ZoneNum).EquipListIndex) - .CoolingPriority(EquipNum); + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int SurfLoop = thisSpace.HTSurfaceFirst; SurfLoop <= thisSpace.HTSurfaceLast; ++SurfLoop) { + if (!state.dataSurface->SurfIntConvSurfHasActiveInIt(SurfLoop)) continue; + if (Surface(SurfLoop).Class == SurfaceClass::Wall || Surface(SurfLoop).Class == SurfaceClass::Door) { + DeltaTemp = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfLoop) - + state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; + if (DeltaTemp > ActiveDelTempThreshold) { // assume heating with wall panel + // system ON is not enough because surfaces can continue to heat because of thermal capacity + EquipOnCount = min(EquipOnCount + 1, MaxZoneEquipmentIdx); + FlowRegimeStack[EquipOnCount] = InConvFlowRegime::A2; + HeatingPriorityStack[EquipOnCount] = + state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ZoneNum).EquipListIndex) + .HeatingPriority(EquipNum); + CoolingPriorityStack[EquipOnCount] = + state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ZoneNum).EquipListIndex) + .CoolingPriority(EquipNum); + } else { // not heating, no special models wall cooling so use simple buoyancy + EquipOnCount = min(EquipOnCount + 1, MaxZoneEquipmentIdx); + FlowRegimeStack[EquipOnCount] = InConvFlowRegime::A3; + HeatingPriorityStack[EquipOnCount] = + state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ZoneNum).EquipListIndex) + .HeatingPriority(EquipNum); + CoolingPriorityStack[EquipOnCount] = + state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ZoneNum).EquipListIndex) + .CoolingPriority(EquipNum); + } } } } @@ -5901,7 +5924,7 @@ void DynamicIntConvSurfaceClassification(EnergyPlusData &state, int const SurfNu // now select which equipment type is dominant compared to all those that are ON if (EquipOnCount > 0) { - if (state.dataHeatBal->ZoneSNLoadPredictedRate(ZoneNum) >= 0.0) { // heating load + if (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).ZoneSNLoadPredictedRate >= 0.0) { // heating load PriorityEquipOn = 1; for (EquipOnLoop = 1; EquipOnLoop <= EquipOnCount; ++EquipOnLoop) { // assume highest priority/first sim order is dominant for flow regime @@ -5909,7 +5932,7 @@ void DynamicIntConvSurfaceClassification(EnergyPlusData &state, int const SurfNu PriorityEquipOn = EquipOnLoop; } } - } else if (state.dataHeatBal->ZoneSNLoadPredictedRate(ZoneNum) < 0.0) { // cooling load + } else if (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).ZoneSNLoadPredictedRate < 0.0) { // cooling load PriorityEquipOn = 1; for (EquipOnLoop = 1; EquipOnLoop <= EquipOnCount; ++EquipOnLoop) { // assume highest priority/first sim order is dominant for flow regime @@ -5929,15 +5952,18 @@ void DynamicIntConvSurfaceClassification(EnergyPlusData &state, int const SurfNu // Calculate Grashof, Reynolds, and Richardson numbers for the zone // Grashof for zone air based on largest delta T between surfaces and zone height - for (int SurfNum = Zone(ZoneNum).HTSurfaceFirst; SurfNum <= Zone(ZoneNum).HTSurfaceLast; ++SurfNum) { - Real64 SurfTemp = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum); - if (SurfTemp < Tmin) - Tmin = SurfTemp; - else if (SurfTemp > Tmax) - Tmax = SurfTemp; + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { + Real64 SurfTemp = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum); + if (SurfTemp < Tmin) + Tmin = SurfTemp; + else if (SurfTemp > Tmax) + Tmax = SurfTemp; + } } GrH = (g * (Tmax - Tmin) * pow_3(Zone(ZoneNum).CeilingHeight)) / - ((state.dataHeatBalFanSys->MAT(ZoneNum) + DataGlobalConstants::KelvinConv) * pow_2(v)); + ((state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT + DataGlobalConstants::KelvinConv) * pow_2(v)); // Reynolds number = Vdot supply / v * cube root of zone volume (Goldstein and Noveselac 2010) if (state.dataLoopNodes->Node(ZoneNode).MassFlowRate > 0.0) { @@ -6077,7 +6103,8 @@ void DynamicIntConvSurfaceClassification(EnergyPlusData &state, int const SurfNu // now finish out specific model eq for this surface - int iDeltaTemp = DeltaTempLambda(state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum), state.dataHeatBalFanSys->MAT(ZoneNum)); + int iDeltaTemp = + DeltaTempLambda(state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum), state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT); int iConvOrient = int(Surface(SurfNum).ConvOrientation); switch (FinalFlowRegime) { @@ -6272,7 +6299,7 @@ void DynamicIntConvSurfaceClassification(EnergyPlusData &state, int const SurfNu case InConvFlowRegime::E: { - Real64 deltaTemp = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum) - state.dataHeatBalFanSys->MAT(ZoneNum); + Real64 deltaTemp = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum) - state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; switch (Surface(SurfNum).Class) { case SurfaceClass::Wall: @@ -6780,7 +6807,7 @@ void CalcUserDefinedInsideHcModel(EnergyPlusData &state, int const SurfNum, int ZoneNum = Surface(SurfNum).Zone; SumMdotTemp = 0.0; SumMdot = 0.0; - SupplyAirTemp = state.dataHeatBalFanSys->MAT(ZoneNum); + SupplyAirTemp = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; if (Zone(ZoneNum).IsControlled) { ZoneNode = Zone(ZoneNum).SystemZoneNodeNumber; AirDensity = PsyRhoAirFnPbTdbW(state, @@ -6813,7 +6840,7 @@ void CalcUserDefinedInsideHcModel(EnergyPlusData &state, int const SurfNum, int switch (UserCurve.ReferenceTempType) { case ConvectionConstants::RefTemp::MeanAirTemp: - tmpAirTemp = state.dataHeatBalFanSys->MAT(ZoneNum); + tmpAirTemp = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; state.dataSurface->SurfTAirRef(SurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; break; case ConvectionConstants::RefTemp::AdjacentAirTemp: diff --git a/src/EnergyPlus/CoolTower.cc b/src/EnergyPlus/CoolTower.cc index 7a919bc3775..db379172912 100644 --- a/src/EnergyPlus/CoolTower.cc +++ b/src/EnergyPlus/CoolTower.cc @@ -56,7 +56,6 @@ #include #include #include -#include #include #include #include @@ -66,6 +65,7 @@ #include #include #include +#include namespace EnergyPlus { @@ -633,19 +633,20 @@ namespace CoolTower { Real64 OutletTemp; // Dry bulb temperature of air at the cooltower outlet Real64 IntHumRat; // Humidity ratio of initialized air - state.dataHeatBalFanSys->MCPTC = 0.0; - state.dataHeatBalFanSys->MCPC = 0.0; - state.dataHeatBalFanSys->CTMFL = 0.0; - auto &Zone(state.dataHeatBal->Zone); for (CoolTowerNum = 1; CoolTowerNum <= (int)state.dataCoolTower->CoolTowerSys.size(); ++CoolTowerNum) { ZoneNum = state.dataCoolTower->CoolTowerSys(CoolTowerNum).ZonePtr; + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); + thisZoneHB.MCPTC = 0.0; + thisZoneHB.MCPC = 0.0; + thisZoneHB.CTMFL = 0.0; if (GetCurrentScheduleValue(state, state.dataCoolTower->CoolTowerSys(CoolTowerNum).SchedPtr) > 0.0) { // check component operation if (state.dataEnvrn->WindSpeed < MinWindSpeed || state.dataEnvrn->WindSpeed > MaxWindSpeed) continue; - if (state.dataHeatBalFanSys->MAT(ZoneNum) < state.dataCoolTower->CoolTowerSys(CoolTowerNum).MinZoneTemp) continue; + if (state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT < state.dataCoolTower->CoolTowerSys(CoolTowerNum).MinZoneTemp) + continue; // Unit is on and simulate this component // Determine the temperature and air flow rate at the cooltower outlet @@ -719,25 +720,22 @@ namespace CoolTower { AirDensity = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, OutletTemp, OutletHumRat); // Outlet air density CVF_ZoneNum = state.dataCoolTower->CoolTowerSys(CoolTowerNum).ActualAirVolFlowRate * GetCurrentScheduleValue(state, state.dataCoolTower->CoolTowerSys(CoolTowerNum).SchedPtr); - state.dataHeatBalFanSys->MCPC(ZoneNum) = CVF_ZoneNum * AirDensity * AirSpecHeat; - state.dataHeatBalFanSys->MCPTC(ZoneNum) = state.dataHeatBalFanSys->MCPC(ZoneNum) * OutletTemp; - state.dataHeatBalFanSys->CTMFL(ZoneNum) = state.dataHeatBalFanSys->MCPC(ZoneNum) / AirSpecHeat; - - state.dataCoolTower->CoolTowerSys(CoolTowerNum).SenHeatPower = - state.dataHeatBalFanSys->MCPC(ZoneNum) * std::abs(state.dataHeatBalFanSys->ZT(ZoneNum) - OutletTemp); - state.dataCoolTower->CoolTowerSys(CoolTowerNum).LatHeatPower = - CVF_ZoneNum * std::abs(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum) - OutletHumRat); + thisZoneHB.MCPC = CVF_ZoneNum * AirDensity * AirSpecHeat; + thisZoneHB.MCPTC = thisZoneHB.MCPC * OutletTemp; + thisZoneHB.CTMFL = thisZoneHB.MCPC / AirSpecHeat; + + state.dataCoolTower->CoolTowerSys(CoolTowerNum).SenHeatPower = thisZoneHB.MCPC * std::abs(thisZoneHB.ZT - OutletTemp); + state.dataCoolTower->CoolTowerSys(CoolTowerNum).LatHeatPower = CVF_ZoneNum * std::abs(thisZoneHB.ZoneAirHumRat - OutletHumRat); state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletTemp = OutletTemp; state.dataCoolTower->CoolTowerSys(CoolTowerNum).OutletHumRat = OutletHumRat; state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirVolFlowRate = CVF_ZoneNum; - state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirMassFlowRate = state.dataHeatBalFanSys->CTMFL(ZoneNum); - state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirVolFlowRateStd = - state.dataHeatBalFanSys->CTMFL(ZoneNum) / state.dataEnvrn->StdRhoAir; + state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirMassFlowRate = thisZoneHB.CTMFL; + state.dataCoolTower->CoolTowerSys(CoolTowerNum).AirVolFlowRateStd = thisZoneHB.CTMFL / state.dataEnvrn->StdRhoAir; state.dataCoolTower->CoolTowerSys(CoolTowerNum).InletDBTemp = Zone(ZoneNum).OutDryBulbTemp; state.dataCoolTower->CoolTowerSys(CoolTowerNum).InletWBTemp = Zone(ZoneNum).OutWetBulbTemp; state.dataCoolTower->CoolTowerSys(CoolTowerNum).InletHumRat = state.dataEnvrn->OutHumRat; state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterConsumpRate = - (std::abs(InletHumRat - OutletHumRat) * state.dataHeatBalFanSys->CTMFL(ZoneNum)) / RhoWater; + (std::abs(InletHumRat - OutletHumRat) * thisZoneHB.CTMFL) / RhoWater; state.dataCoolTower->CoolTowerSys(CoolTowerNum).CoolTWaterStarvMakeupRate = 0.0; // initialize -- calc in update state.dataCoolTower->CoolTowerSys(CoolTowerNum).PumpElecPower = state.dataCoolTower->CoolTowerSys(CoolTowerNum).RatedPumpPower * PumpPartLoadRat; diff --git a/src/EnergyPlus/CrossVentMgr.cc b/src/EnergyPlus/CrossVentMgr.cc index 982f7f48176..7ce42a08e76 100644 --- a/src/EnergyPlus/CrossVentMgr.cc +++ b/src/EnergyPlus/CrossVentMgr.cc @@ -69,6 +69,7 @@ #include #include #include +#include namespace EnergyPlus { @@ -167,7 +168,6 @@ namespace CrossVentMgr { // initial calculations and averages the final result comparing the position of the surface with // the interface subzone height. - using namespace DataHeatBalFanSys; using namespace DataEnvironment; using namespace DataHeatBalance; using ScheduleManager::GetScheduleIndex; // , GetDayScheduleValues @@ -365,20 +365,14 @@ namespace CrossVentMgr { // MODIFIED 8/2013 - Sam Brunswick // To incorporate an improved model // and add modeling of multiple jets - // RE-ENGINEERED - // PURPOSE OF THIS SUBROUTINE: // Subroutine for parameter actualization in the UCSD Cross Ventilation model. using namespace Psychrometrics; - using namespace DataHeatBalFanSys; Real64 constexpr MinUin(0.2); - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int Ctd; // counter - int Ctd2; // counter - int OPtr; // counter Real64 Uin; // Inflow air velocity [m/s] Real64 CosPhi; // Angle (in degrees) between the wind and the outward normal of the dominant surface Real64 SurfNorm; // Outward normal of surface @@ -398,13 +392,15 @@ namespace CrossVentMgr { int NodeNum1(0); // The first node number in an AirflowNetwork linkage data int NodeNum2(0); // The Second node number in an AirflowNetwork linkage data - auto &Zone(state.dataHeatBal->Zone); - + assert(state.dataRoomAirMod->AirModel.allocated()); state.dataRoomAirMod->RecInflowRatio(ZoneNum) = 0.0; + auto const &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); // Identify the dominant aperture: MaxSurf = state.dataRoomAirMod->AirflowNetworkSurfaceUCSDCV(1, ZoneNum); - if (state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).Zone == ZoneNum) { + int const surfNum = state.afn->MultizoneSurfaceData(MaxSurf).SurfNum; + auto const &thisSurface = state.dataSurface->Surface(surfNum); + if (thisSurface.Zone == ZoneNum) { // this is a direct airflow network aperture SumToZone = state.afn->AirflowNetworkLinkSimu(state.dataRoomAirMod->AirflowNetworkSurfaceUCSDCV(1, ZoneNum)).VolFLOW2; MaxFlux = state.afn->AirflowNetworkLinkSimu(state.dataRoomAirMod->AirflowNetworkSurfaceUCSDCV(1, ZoneNum)).VolFLOW2; @@ -414,7 +410,7 @@ namespace CrossVentMgr { MaxFlux = state.afn->AirflowNetworkLinkSimu(state.dataRoomAirMod->AirflowNetworkSurfaceUCSDCV(1, ZoneNum)).VolFLOW; } - for (Ctd2 = 2; Ctd2 <= state.dataRoomAirMod->AirflowNetworkSurfaceUCSDCV(0, ZoneNum); ++Ctd2) { + for (int Ctd2 = 2; Ctd2 <= state.dataRoomAirMod->AirflowNetworkSurfaceUCSDCV(0, ZoneNum); ++Ctd2) { if (state.dataSurface->Surface(state.afn->MultizoneSurfaceData(state.dataRoomAirMod->AirflowNetworkSurfaceUCSDCV(Ctd2, ZoneNum)).SurfNum) .Zone == ZoneNum) { if (state.afn->AirflowNetworkLinkSimu(state.dataRoomAirMod->AirflowNetworkSurfaceUCSDCV(Ctd2, ZoneNum)).VolFLOW2 > MaxFlux) { @@ -432,7 +428,7 @@ namespace CrossVentMgr { } // Check if wind direction is within +/- 90 degrees of the outward normal of the dominant surface - SurfNorm = state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).Azimuth; + SurfNorm = thisSurface.Azimuth; CosPhi = std::cos((state.dataEnvrn->WindDir - SurfNorm) * DataGlobalConstants::DegToRadians); if (CosPhi <= 0) { state.dataRoomAirMod->AirModel(ZoneNum).SimAirModel = false; @@ -444,34 +440,28 @@ namespace CrossVentMgr { state.dataRoomAirMod->Urec(ZoneNum) = 0.0; state.dataRoomAirMod->Ujet(ZoneNum) = 0.0; state.dataRoomAirMod->Qrec(ZoneNum) = 0.0; - if (state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond > 0) { - state.dataRoomAirMod->Tin(ZoneNum) = state.dataHeatBalFanSys->MAT( - state.dataSurface->Surface(state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond).Zone); - } else if (state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond == ExternalEnvironment) { - state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum); - } else if (state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond == Ground) { - state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum); - } else if (state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt || - state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond == OtherSideCoefCalcExt) { - OPtr = state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).OSCPtr; - state.dataSurface->OSC(OPtr).OSCTempCalc = - (state.dataSurface->OSC(OPtr).ZoneAirTempCoef * state.dataHeatBalFanSys->MAT(ZoneNum) + - state.dataSurface->OSC(OPtr).ExtDryBulbCoef * - state.dataSurface->SurfOutDryBulbTemp(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum) + - state.dataSurface->OSC(OPtr).ConstTempCoef * state.dataSurface->OSC(OPtr).ConstTemp + - state.dataSurface->OSC(OPtr).GroundTempCoef * state.dataEnvrn->GroundTemp + - state.dataSurface->OSC(OPtr).WindSpeedCoef * - state.dataSurface->SurfOutWindSpeed(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum) * - state.dataSurface->SurfOutDryBulbTemp(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum)); - state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->OSC(OPtr).OSCTempCalc; + if (thisSurface.ExtBoundCond > 0) { + state.dataRoomAirMod->Tin(ZoneNum) = + state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataSurface->Surface(thisSurface.ExtBoundCond).Zone).MAT; + } else if (thisSurface.ExtBoundCond == ExternalEnvironment) { + state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum); + } else if (thisSurface.ExtBoundCond == Ground) { + state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum); + } else if (thisSurface.ExtBoundCond == OtherSideCoefNoCalcExt || thisSurface.ExtBoundCond == OtherSideCoefCalcExt) { + auto &thisOSC = state.dataSurface->OSC(thisSurface.OSCPtr); + thisOSC.OSCTempCalc = + (thisOSC.ZoneAirTempCoef * thisZoneHB.MAT + thisOSC.ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(surfNum) + + thisOSC.ConstTempCoef * thisOSC.ConstTemp + thisOSC.GroundTempCoef * state.dataEnvrn->GroundTemp + + thisOSC.WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(surfNum) * state.dataSurface->SurfOutDryBulbTemp(surfNum)); + state.dataRoomAirMod->Tin(ZoneNum) = thisOSC.OSCTempCalc; } else { - state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum); + state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum); } return; } // Calculate the opening area for all apertures - for (Ctd = 1; Ctd <= state.dataRoomAirMod->AirflowNetworkSurfaceUCSDCV(0, ZoneNum); ++Ctd) { + for (int Ctd = 1; Ctd <= state.dataRoomAirMod->AirflowNetworkSurfaceUCSDCV(0, ZoneNum); ++Ctd) { int cCompNum = state.afn->AirflowNetworkLinkageData(Ctd).CompNum; if (state.afn->AirflowNetworkCompData(cCompNum).CompTypeNum == AirflowNetwork::iComponentTypeNum::DOP) { state.dataRoomAirMod->CVJetRecFlows(Ctd, ZoneNum).Area = state.dataRoomAirMod->SurfParametersCVDV(Ctd).Width * @@ -484,7 +474,7 @@ namespace CrossVentMgr { ShowSevereError( state, "RoomAirModelCrossVent:EvolveParaUCSDCV: Illegal leakage component referenced in the cross ventilation room air model"); ShowContinueError(state, - "Surface " + state.afn->AirflowNetworkLinkageData(Ctd).Name + " in zone " + Zone(ZoneNum).Name + + "Surface " + state.afn->AirflowNetworkLinkageData(Ctd).Name + " in zone " + state.dataHeatBal->Zone(ZoneNum).Name + " uses leakage component " + state.afn->AirflowNetworkLinkageData(Ctd).CompName); ShowContinueError(state, "Only leakage component types AirflowNetwork:MultiZone:Component:DetailedOpening and "); ShowContinueError(state, "AirflowNetwork:MultiZone:Surface:Crack can be used with the cross ventilation room air model"); @@ -496,8 +486,8 @@ namespace CrossVentMgr { // Droom the distance between the average point of the base surface of the airflow network Surface (if the base surface // is a Window or Door it looks for the second base surface). // Dstar is Droom corrected for wind angle - Wroom = Zone(ZoneNum).Volume / Zone(ZoneNum).FloorArea; - auto const &baseSurface(state.dataSurface->Surface(state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).BaseSurf)); + Wroom = state.dataHeatBal->Zone(ZoneNum).Volume / state.dataHeatBal->Zone(ZoneNum).FloorArea; + auto const &baseSurface(state.dataSurface->Surface(thisSurface.BaseSurf)); if ((baseSurface.Sides == 3) || (baseSurface.Sides == 4)) { XX = baseSurface.Centroid.x; YY = baseSurface.Centroid.y; @@ -519,7 +509,7 @@ namespace CrossVentMgr { } Real64 const Wroom_2(pow_2(Wroom)); - for (Ctd = state.dataUCSDShared->PosZ_Wall(2 * ZoneNum - 1); Ctd <= state.dataUCSDShared->PosZ_Wall(2 * ZoneNum); ++Ctd) { + for (int Ctd = state.dataUCSDShared->PosZ_Wall(2 * ZoneNum - 1); Ctd <= state.dataUCSDShared->PosZ_Wall(2 * ZoneNum); ++Ctd) { if ((state.dataSurface->Surface(state.dataUCSDShared->APos_Wall(Ctd)).Sides == 3) || (state.dataSurface->Surface(state.dataUCSDShared->APos_Wall(Ctd)).Sides == 4)) { XX_Wall = state.dataSurface->Surface(state.dataUCSDShared->APos_Wall(Ctd)).Centroid.x; @@ -548,11 +538,11 @@ namespace CrossVentMgr { } // Room area - Aroom = Zone(ZoneNum).Volume / state.dataRoomAirMod->Droom(ZoneNum); + Aroom = state.dataHeatBal->Zone(ZoneNum).Volume / state.dataRoomAirMod->Droom(ZoneNum); // Populate an array of inflow volume fluxes (Fin) for all apertures in the zone // Calculate inflow velocity (%Uin) for each aperture in the zone - for (Ctd = 1; Ctd <= state.dataRoomAirMod->AirflowNetworkSurfaceUCSDCV(0, ZoneNum); ++Ctd) { + for (int Ctd = 1; Ctd <= state.dataRoomAirMod->AirflowNetworkSurfaceUCSDCV(0, ZoneNum); ++Ctd) { if (state.dataSurface->Surface(state.afn->MultizoneSurfaceData(Ctd).SurfNum).Zone == ZoneNum) { // this is a direct airflow network aperture state.dataRoomAirMod->CVJetRecFlows(Ctd, ZoneNum).Fin = @@ -575,7 +565,7 @@ namespace CrossVentMgr { // Calculate the total area of all active apertures ActiveSurfNum = 0.0; state.dataRoomAirMod->Ain(ZoneNum) = 0.0; - for (Ctd = 1; Ctd <= state.dataRoomAirMod->AirflowNetworkSurfaceUCSDCV(0, ZoneNum); ++Ctd) { + for (int Ctd = 1; Ctd <= state.dataRoomAirMod->AirflowNetworkSurfaceUCSDCV(0, ZoneNum); ++Ctd) { if (state.dataRoomAirMod->CVJetRecFlows(Ctd, ZoneNum).Uin <= MinUin) { state.dataRoomAirMod->CVJetRecFlows(Ctd, ZoneNum).FlowFlag = 0; } else { @@ -589,28 +579,22 @@ namespace CrossVentMgr { // Verify if any of the apertures have minimum flow if (ActiveSurfNum == 0) { state.dataRoomAirMod->AirModel(ZoneNum).SimAirModel = false; - if (state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond > 0) { - state.dataRoomAirMod->Tin(ZoneNum) = state.dataHeatBalFanSys->MAT( - state.dataSurface->Surface(state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond).Zone); - } else if (state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond == ExternalEnvironment) { - state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum); - } else if (state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond == Ground) { - state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum); - } else if (state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt || - state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond == OtherSideCoefCalcExt) { - OPtr = state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).OSCPtr; - state.dataSurface->OSC(OPtr).OSCTempCalc = - (state.dataSurface->OSC(OPtr).ZoneAirTempCoef * state.dataHeatBalFanSys->MAT(ZoneNum) + - state.dataSurface->OSC(OPtr).ExtDryBulbCoef * - state.dataSurface->SurfOutDryBulbTemp(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum) + - state.dataSurface->OSC(OPtr).ConstTempCoef * state.dataSurface->OSC(OPtr).ConstTemp + - state.dataSurface->OSC(OPtr).GroundTempCoef * state.dataEnvrn->GroundTemp + - state.dataSurface->OSC(OPtr).WindSpeedCoef * - state.dataSurface->SurfOutWindSpeed(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum) * - state.dataSurface->SurfOutDryBulbTemp(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum)); - state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->OSC(OPtr).OSCTempCalc; + if (thisSurface.ExtBoundCond > 0) { + state.dataRoomAirMod->Tin(ZoneNum) = + state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataSurface->Surface(thisSurface.ExtBoundCond).Zone).MAT; + } else if (thisSurface.ExtBoundCond == ExternalEnvironment) { + state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum); + } else if (thisSurface.ExtBoundCond == Ground) { + state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum); + } else if (thisSurface.ExtBoundCond == OtherSideCoefNoCalcExt || thisSurface.ExtBoundCond == OtherSideCoefCalcExt) { + auto &thisOSC = state.dataSurface->OSC(thisSurface.OSCPtr); + thisOSC.OSCTempCalc = + (thisOSC.ZoneAirTempCoef * thisZoneHB.MAT + thisOSC.ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(surfNum) + + thisOSC.ConstTempCoef * thisOSC.ConstTemp + thisOSC.GroundTempCoef * state.dataEnvrn->GroundTemp + + thisOSC.WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(surfNum) * state.dataSurface->SurfOutDryBulbTemp(surfNum)); + state.dataRoomAirMod->Tin(ZoneNum) = thisOSC.OSCTempCalc; } else { - state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum); + state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum); } state.dataRoomAirMod->Urec(ZoneNum) = 0.0; state.dataRoomAirMod->Ujet(ZoneNum) = 0.0; @@ -627,7 +611,7 @@ namespace CrossVentMgr { // Calculate Qtot, the total volumetric flow rate through all active openings in the zone Uin = 0.0; - for (Ctd = 1; Ctd <= state.dataRoomAirMod->AirflowNetworkSurfaceUCSDCV(0, ZoneNum); ++Ctd) { + for (int Ctd = 1; Ctd <= state.dataRoomAirMod->AirflowNetworkSurfaceUCSDCV(0, ZoneNum); ++Ctd) { Uin += state.dataRoomAirMod->CVJetRecFlows(Ctd, ZoneNum).Area * state.dataRoomAirMod->CVJetRecFlows(Ctd, ZoneNum).Uin * state.dataRoomAirMod->CVJetRecFlows(Ctd, ZoneNum).FlowFlag / state.dataRoomAirMod->Ain(ZoneNum); } @@ -644,35 +628,29 @@ namespace CrossVentMgr { auto &e(flows(i)); e.Ujet = e.Urec = 0.0; } - if (state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond > 0) { - state.dataRoomAirMod->Tin(ZoneNum) = state.dataHeatBalFanSys->MAT( - state.dataSurface->Surface(state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond).Zone); - } else if (state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond == ExternalEnvironment) { - state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum); - } else if (state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond == Ground) { - state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum); - } else if (state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt || - state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond == OtherSideCoefCalcExt) { - OPtr = state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).OSCPtr; - state.dataSurface->OSC(OPtr).OSCTempCalc = - (state.dataSurface->OSC(OPtr).ZoneAirTempCoef * state.dataHeatBalFanSys->MAT(ZoneNum) + - state.dataSurface->OSC(OPtr).ExtDryBulbCoef * - state.dataSurface->SurfOutDryBulbTemp(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum) + - state.dataSurface->OSC(OPtr).ConstTempCoef * state.dataSurface->OSC(OPtr).ConstTemp + - state.dataSurface->OSC(OPtr).GroundTempCoef * state.dataEnvrn->GroundTemp + - state.dataSurface->OSC(OPtr).WindSpeedCoef * - state.dataSurface->SurfOutWindSpeed(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum) * - state.dataSurface->SurfOutDryBulbTemp(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum)); - state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->OSC(OPtr).OSCTempCalc; + if (thisSurface.ExtBoundCond > 0) { + state.dataRoomAirMod->Tin(ZoneNum) = + state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataSurface->Surface(thisSurface.ExtBoundCond).Zone).MAT; + } else if (thisSurface.ExtBoundCond == ExternalEnvironment) { + state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum); + } else if (thisSurface.ExtBoundCond == Ground) { + state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum); + } else if (thisSurface.ExtBoundCond == OtherSideCoefNoCalcExt || thisSurface.ExtBoundCond == OtherSideCoefCalcExt) { + auto &thisOSC = state.dataSurface->OSC(thisSurface.OSCPtr); + thisOSC.OSCTempCalc = + (thisOSC.ZoneAirTempCoef * thisZoneHB.MAT + thisOSC.ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(surfNum) + + thisOSC.ConstTempCoef * thisOSC.ConstTemp + thisOSC.GroundTempCoef * state.dataEnvrn->GroundTemp + + thisOSC.WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(surfNum) * state.dataSurface->SurfOutDryBulbTemp(surfNum)); + state.dataRoomAirMod->Tin(ZoneNum) = thisOSC.OSCTempCalc; } else { - state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum); + state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum); } return; } // Evaluate parameter that determines whether recirculations are present - for (Ctd = 1; Ctd <= state.dataRoomAirMod->TotUCSDCV; ++Ctd) { + for (int Ctd = 1; Ctd <= state.dataRoomAirMod->TotUCSDCV; ++Ctd) { if (ZoneNum == state.dataRoomAirMod->ZoneUCSDCV(Ctd).ZonePtr) { if (state.dataRoomAirMod->Ain(ZoneNum) / Aroom > 1.0 / 2.0) { state.dataRoomAirMod->JetRecAreaRatio(ZoneNum) = 1.0; @@ -693,7 +671,7 @@ namespace CrossVentMgr { auto &e(flows(i)); e.Ujet = e.Urec = e.Qrec = 0.0; } - for (Ctd = 1; Ctd <= state.dataRoomAirMod->AirflowNetworkSurfaceUCSDCV(0, ZoneNum); ++Ctd) { + for (int Ctd = 1; Ctd <= state.dataRoomAirMod->AirflowNetworkSurfaceUCSDCV(0, ZoneNum); ++Ctd) { if (state.dataRoomAirMod->CVJetRecFlows(Ctd, ZoneNum).Uin != 0) { Real64 dstarexp = max(state.dataRoomAirMod->Dstar(ZoneNum) / (6.0 * std::sqrt(state.dataRoomAirMod->CVJetRecFlows(Ctd, ZoneNum).Area)), 1.0); @@ -741,75 +719,64 @@ namespace CrossVentMgr { } // Set Tin based on external conditions of the dominant aperture - if (state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond <= 0) { - if (state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond == ExternalEnvironment) { - state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum); - } else if (state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond == Ground) { - state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum); - } else if (state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt || - state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond == OtherSideCoefCalcExt) { - OPtr = state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).OSCPtr; - state.dataSurface->OSC(OPtr).OSCTempCalc = - (state.dataSurface->OSC(OPtr).ZoneAirTempCoef * state.dataHeatBalFanSys->MAT(ZoneNum) + - state.dataSurface->OSC(OPtr).ExtDryBulbCoef * - state.dataSurface->SurfOutDryBulbTemp(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum) + - state.dataSurface->OSC(OPtr).ConstTempCoef * state.dataSurface->OSC(OPtr).ConstTemp + - state.dataSurface->OSC(OPtr).GroundTempCoef * state.dataEnvrn->GroundTemp + - state.dataSurface->OSC(OPtr).WindSpeedCoef * - state.dataSurface->SurfOutWindSpeed(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum) * - state.dataSurface->SurfOutDryBulbTemp(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum)); - state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->OSC(OPtr).OSCTempCalc; + if (thisSurface.ExtBoundCond <= 0) { + if (thisSurface.ExtBoundCond == ExternalEnvironment) { + state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum); + } else if (thisSurface.ExtBoundCond == Ground) { + state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum); + } else if (thisSurface.ExtBoundCond == OtherSideCoefNoCalcExt || thisSurface.ExtBoundCond == OtherSideCoefCalcExt) { + auto &thisOSC = state.dataSurface->OSC(thisSurface.OSCPtr); + thisOSC.OSCTempCalc = + (thisOSC.ZoneAirTempCoef * thisZoneHB.MAT + thisOSC.ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(surfNum) + + thisOSC.ConstTempCoef * thisOSC.ConstTemp + thisOSC.GroundTempCoef * state.dataEnvrn->GroundTemp + + thisOSC.WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(surfNum) * state.dataSurface->SurfOutDryBulbTemp(surfNum)); + state.dataRoomAirMod->Tin(ZoneNum) = thisOSC.OSCTempCalc; } else { - state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum); + state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum); } } else { // adiabatic surface - if (state.afn->MultizoneSurfaceData(MaxSurf).SurfNum == - state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond) { + if (surfNum == thisSurface.ExtBoundCond) { NodeNum1 = state.afn->AirflowNetworkLinkageData(MaxSurf).NodeNums[0]; NodeNum2 = state.afn->AirflowNetworkLinkageData(MaxSurf).NodeNums[1]; - if (state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).Zone == ZoneNum) { + if (thisSurface.Zone == ZoneNum) { if (state.afn->AirflowNetworkNodeData(NodeNum1).EPlusZoneNum <= 0) { - state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum); + state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum); } else if (state.dataRoomAirMod->AirModel(state.afn->AirflowNetworkNodeData(NodeNum1).EPlusZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::UCSDCV) { state.dataRoomAirMod->Tin(ZoneNum) = state.dataRoomAirMod->RoomOutflowTemp(state.afn->AirflowNetworkNodeData(NodeNum1).EPlusZoneNum); } else { - state.dataRoomAirMod->Tin(ZoneNum) = state.dataHeatBalFanSys->MAT(state.afn->AirflowNetworkNodeData(NodeNum1).EPlusZoneNum); + state.dataRoomAirMod->Tin(ZoneNum) = + state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.afn->AirflowNetworkNodeData(NodeNum1).EPlusZoneNum).MAT; } } else { if (state.afn->AirflowNetworkNodeData(NodeNum2).EPlusZoneNum <= 0) { - state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum); + state.dataRoomAirMod->Tin(ZoneNum) = state.dataSurface->SurfOutDryBulbTemp(surfNum); } else if (state.dataRoomAirMod->AirModel(state.afn->AirflowNetworkNodeData(NodeNum2).EPlusZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::UCSDCV) { state.dataRoomAirMod->Tin(ZoneNum) = state.dataRoomAirMod->RoomOutflowTemp(state.afn->AirflowNetworkNodeData(NodeNum2).EPlusZoneNum); } else { - state.dataRoomAirMod->Tin(ZoneNum) = state.dataHeatBalFanSys->MAT(state.afn->AirflowNetworkNodeData(NodeNum2).EPlusZoneNum); + state.dataRoomAirMod->Tin(ZoneNum) = + state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.afn->AirflowNetworkNodeData(NodeNum2).EPlusZoneNum).MAT; } } - } else if ((state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).Zone == ZoneNum) && - (state.dataRoomAirMod - ->AirModel( - state.dataSurface->Surface(state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond) - .Zone) - .AirModelType == DataRoomAirModel::RoomAirModel::UCSDCV)) { - state.dataRoomAirMod->Tin(ZoneNum) = state.dataRoomAirMod->RoomOutflowTemp( - state.dataSurface->Surface(state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond).Zone); - } else if ((state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).Zone != ZoneNum) && - (state.dataRoomAirMod->AirModel(state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).Zone) - .AirModelType == DataRoomAirModel::RoomAirModel::UCSDCV)) { - state.dataRoomAirMod->Tin(ZoneNum) = state.dataRoomAirMod->RoomOutflowTemp(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum); + } else if ((thisSurface.Zone == ZoneNum) && + (state.dataRoomAirMod->AirModel(state.dataSurface->Surface(thisSurface.ExtBoundCond).Zone).AirModelType == + DataRoomAirModel::RoomAirModel::UCSDCV)) { + state.dataRoomAirMod->Tin(ZoneNum) = state.dataRoomAirMod->RoomOutflowTemp(state.dataSurface->Surface(thisSurface.ExtBoundCond).Zone); + } else if ((thisSurface.Zone != ZoneNum) && + (state.dataRoomAirMod->AirModel(thisSurface.Zone).AirModelType == DataRoomAirModel::RoomAirModel::UCSDCV)) { + state.dataRoomAirMod->Tin(ZoneNum) = state.dataRoomAirMod->RoomOutflowTemp(surfNum); } else { - if (state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).Zone == ZoneNum) { - state.dataRoomAirMod->Tin(ZoneNum) = state.dataHeatBalFanSys->MAT( - state.dataSurface->Surface(state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).ExtBoundCond).Zone); - } else { + if (thisSurface.Zone == ZoneNum) { state.dataRoomAirMod->Tin(ZoneNum) = - state.dataHeatBalFanSys->MAT(state.dataSurface->Surface(state.afn->MultizoneSurfaceData(MaxSurf).SurfNum).Zone); + state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataSurface->Surface(thisSurface.ExtBoundCond).Zone).MAT; + } else { + state.dataRoomAirMod->Tin(ZoneNum) = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisSurface.Zone).MAT; } } } @@ -834,11 +801,8 @@ namespace CrossVentMgr { // Work funded by the California Energy Comission. More information on the model can found in: // "Simplified Models for Heat Transfer in Rooms" G. Carrilho da Graca, Ph.D. thesis UCSD. December 2003. - using namespace DataHeatBalFanSys; using namespace DataEnvironment; using namespace DataHeatBalance; - using InternalHeatGains::SumAllInternalConvectionGains; - using InternalHeatGains::SumAllReturnAirConvectionGains; using Psychrometrics::PsyCpAirFnW; using Psychrometrics::PsyRhoAirFnPbTdbW; using ScheduleManager::GetCurrentScheduleValue; @@ -854,7 +818,6 @@ namespace CrossVentMgr { auto &Zone(state.dataHeatBal->Zone); - int Ctd; Real64 MCpT_Total; Real64 L; Real64 ZoneMult; // total zone multiplier @@ -862,30 +825,29 @@ namespace CrossVentMgr { GainsFrac = 0.0; ZoneMult = Zone(ZoneNum).Multiplier * Zone(ZoneNum).ListMultiplier; + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); - for (Ctd = 1; Ctd <= state.dataRoomAirMod->TotUCSDCV; ++Ctd) { + for (int Ctd = 1; Ctd <= state.dataRoomAirMod->TotUCSDCV; ++Ctd) { if (ZoneNum == state.dataRoomAirMod->ZoneUCSDCV(Ctd).ZonePtr) { GainsFrac = GetCurrentScheduleValue(state, state.dataRoomAirMod->ZoneUCSDCV(Ctd).SchedGainsPtr); } } - ConvGains = SumAllInternalConvectionGains(state, ZoneNum); + ConvGains = InternalHeatGains::zoneSumAllInternalConvectionGains(state, ZoneNum); ConvGains += state.dataHeatBalFanSys->SumConvHTRadSys(ZoneNum) + state.dataHeatBalFanSys->SumConvPool(ZoneNum) + - state.dataHeatBalFanSys->SysDepZoneLoadsLagged(ZoneNum) + state.dataHeatBalFanSys->NonAirSystemResponse(ZoneNum) / ZoneMult; + thisZoneHB.SysDepZoneLoadsLagged + thisZoneHB.NonAirSystemResponse / ZoneMult; // Add heat to return air if zonal system (no return air) or cycling system (return air frequently very low or zero) if (Zone(ZoneNum).NoHeatToReturnAir) { - RetAirConvGain = SumAllReturnAirConvectionGains(state, ZoneNum, 0); + RetAirConvGain = InternalHeatGains::zoneSumAllReturnAirConvectionGains(state, ZoneNum, 0); ConvGains += RetAirConvGain; } ConvGainsJet = ConvGains * GainsFrac; ConvGainsRec = ConvGains * (1.0 - GainsFrac); - MCp_Total = state.dataHeatBalFanSys->MCPI(ZoneNum) + state.dataHeatBalFanSys->MCPV(ZoneNum) + state.dataHeatBalFanSys->MCPM(ZoneNum) + - state.dataHeatBalFanSys->MCPE(ZoneNum) + state.dataHeatBalFanSys->MCPC(ZoneNum) + state.dataHeatBalFanSys->MDotCPOA(ZoneNum); - MCpT_Total = state.dataHeatBalFanSys->MCPTI(ZoneNum) + state.dataHeatBalFanSys->MCPTV(ZoneNum) + state.dataHeatBalFanSys->MCPTM(ZoneNum) + - state.dataHeatBalFanSys->MCPTE(ZoneNum) + state.dataHeatBalFanSys->MCPTC(ZoneNum) + - state.dataHeatBalFanSys->MDotCPOA(ZoneNum) * Zone(ZoneNum).OutDryBulbTemp; + MCp_Total = thisZoneHB.MCPI + thisZoneHB.MCPV + thisZoneHB.MCPM + thisZoneHB.MCPE + thisZoneHB.MCPC + thisZoneHB.MDotCPOA; + MCpT_Total = thisZoneHB.MCPTI + thisZoneHB.MCPTV + thisZoneHB.MCPTM + thisZoneHB.MCPTE + thisZoneHB.MCPTC + + thisZoneHB.MDotCPOA * Zone(ZoneNum).OutDryBulbTemp; if (state.afn->simulation_control.type == AirflowNetwork::ControlType::MultizoneWithoutDistribution) { MCp_Total = state.afn->exchangeData(ZoneNum).SumMCp + state.afn->exchangeData(ZoneNum).SumMVCp + state.afn->exchangeData(ZoneNum).SumMMCp; @@ -900,7 +862,7 @@ namespace CrossVentMgr { //=============================== CROSS VENTILATION Calculation ============================================== state.dataRoomAirMod->ZoneCVisMixing(ZoneNum) = 0.0; state.dataRoomAirMod->ZoneCVhasREC(ZoneNum) = 1.0; - for (Ctd = 1; Ctd <= 4; ++Ctd) { + for (int Ctd = 1; Ctd <= 4; ++Ctd) { HcUCSDCV(state, ZoneNum); if (state.dataRoomAirMod->JetRecAreaRatio(ZoneNum) != 1.0) { state.dataRoomAirMod->ZTREC(ZoneNum) = @@ -936,8 +898,8 @@ namespace CrossVentMgr { e.Ujet = 0.0; e.Urec = 0.0; } - for (Ctd = 1; Ctd <= 3; ++Ctd) { - ZTAveraged = state.dataHeatBalFanSys->MAT(ZoneNum); + for (int Ctd = 1; Ctd <= 3; ++Ctd) { + ZTAveraged = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; state.dataRoomAirMod->RoomOutflowTemp(ZoneNum) = ZTAveraged; state.dataRoomAirMod->ZTJET(ZoneNum) = ZTAveraged; state.dataRoomAirMod->ZTREC(ZoneNum) = ZTAveraged; @@ -946,7 +908,7 @@ namespace CrossVentMgr { state.dataRoomAirMod->ZTJET(ZoneNum) = ZTAveraged; state.dataRoomAirMod->ZTREC(ZoneNum) = ZTAveraged; HcUCSDCV(state, ZoneNum); - ZTAveraged = state.dataHeatBalFanSys->MAT(ZoneNum); + ZTAveraged = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; state.dataRoomAirMod->RoomOutflowTemp(ZoneNum) = ZTAveraged; state.dataRoomAirMod->ZTJET(ZoneNum) = ZTAveraged; state.dataRoomAirMod->ZTREC(ZoneNum) = ZTAveraged; @@ -968,8 +930,8 @@ namespace CrossVentMgr { e.Ujet = 0.0; e.Urec = 0.0; } - for (Ctd = 1; Ctd <= 3; ++Ctd) { - ZTAveraged = state.dataHeatBalFanSys->MAT(ZoneNum); + for (int Ctd = 1; Ctd <= 3; ++Ctd) { + ZTAveraged = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; state.dataRoomAirMod->RoomOutflowTemp(ZoneNum) = ZTAveraged; state.dataRoomAirMod->ZTJET(ZoneNum) = ZTAveraged; state.dataRoomAirMod->ZTREC(ZoneNum) = ZTAveraged; @@ -978,7 +940,7 @@ namespace CrossVentMgr { state.dataRoomAirMod->ZTJET(ZoneNum) = ZTAveraged; state.dataRoomAirMod->ZTREC(ZoneNum) = ZTAveraged; HcUCSDCV(state, ZoneNum); - ZTAveraged = state.dataHeatBalFanSys->MAT(ZoneNum); + ZTAveraged = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; state.dataRoomAirMod->RoomOutflowTemp(ZoneNum) = ZTAveraged; state.dataRoomAirMod->ZTJET(ZoneNum) = ZTAveraged; state.dataRoomAirMod->ZTREC(ZoneNum) = ZTAveraged; diff --git a/src/EnergyPlus/DElightManagerF.cc b/src/EnergyPlus/DElightManagerF.cc index 284909d8b3b..b516234b5fe 100644 --- a/src/EnergyPlus/DElightManagerF.cc +++ b/src/EnergyPlus/DElightManagerF.cc @@ -137,7 +137,6 @@ namespace DElightManagerF { // SUBROUTINE LOCAL VARIABLE DECLARATIONS: int iNumDElightZones; // Counter for Thermal Zones with hosted Daylighting:DElight objects int iNumOpaqueSurfs; // Counter for opaque surfaces in each zone - int iSurfaceFirst; // starting loop variable for surfaces int iNumWindows; // Counter for windows hosted in each surface int iconstruct; // Index for construction type of surfaces int iMatlLayer; // Index for the outside (i.e., 1st) Material Layer for a Construction @@ -313,122 +312,95 @@ namespace DElightManagerF { // Zone Surface Data Section // Count the number of opaque surfaces bounding the current zone iNumOpaqueSurfs = 0; - iSurfaceFirst = zn.HTSurfaceFirst; - int const iSurfaceLast = zn.HTSurfaceLast; // ending loop variable for surfaces - - for (int isurf = iSurfaceFirst; isurf <= iSurfaceLast; ++isurf) { - auto &surf(state.dataSurface->Surface(isurf)); - if (surf.Class == SurfaceClass::Wall) ++iNumOpaqueSurfs; - if (surf.Class == SurfaceClass::Roof) ++iNumOpaqueSurfs; - if (surf.Class == SurfaceClass::Floor) ++iNumOpaqueSurfs; + for (int spaceNum : zn.spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int isurf = thisSpace.HTSurfaceFirst; isurf <= thisSpace.HTSurfaceLast; ++isurf) { + auto &surf(state.dataSurface->Surface(isurf)); + if (surf.Class == SurfaceClass::Wall) ++iNumOpaqueSurfs; + if (surf.Class == SurfaceClass::Roof) ++iNumOpaqueSurfs; + if (surf.Class == SurfaceClass::Floor) ++iNumOpaqueSurfs; + } } // Zone Opaque Surface loop print(delightInFile, Format_906, iNumOpaqueSurfs); // Write each opaque bounding Surface to the DElight input file - for (int isurf = iSurfaceFirst; isurf <= iSurfaceLast; ++isurf) { - - auto &surf(state.dataSurface->Surface(isurf)); - - // Only process "opaque bounding" surface types - if ((surf.Class == SurfaceClass::Wall) || (surf.Class == SurfaceClass::Roof) || (surf.Class == SurfaceClass::Floor)) { - - // Get the Construction index for this Surface - iconstruct = surf.Construction; - - // Is this Surface exposed to the exterior? - if (surf.ExtSolar) { - // Get the index for the outside (i.e., 1st) Material Layer for this Construction - iMatlLayer = state.dataConstruction->Construct(iconstruct).LayerPoint(1); - // Get the outside visible reflectance of this material layer - // (since Construct(iconstruct)%ReflectVisDiffFront always appears to == 0.0) - rExtVisRefl = 1.0 - state.dataMaterial->Material(iMatlLayer).AbsorpVisible; - } else { - rExtVisRefl = 0.0; - } - - // Remove any blanks from the Surface Name for ease of input to DElight - cNameWOBlanks = ReplaceBlanksWithUnderscores(surf.Name); - print(delightInFile, - Format_907, - cNameWOBlanks, - surf.Azimuth, - surf.Tilt, - state.dataConstruction->Construct(iconstruct).ReflectVisDiffBack, - rExtVisRefl, - surf.Sides); - - // Write out the vertex coordinates for each vertex - int const iNumVertices = surf.Sides; // Counter for surface vertices - for (int ivert = 1; ivert <= iNumVertices; ++ivert) { - print( - delightInFile, Format_908, surf.Vertex(ivert).x * M2FT, surf.Vertex(ivert).y * M2FT, surf.Vertex(ivert).z * M2FT); - } - - // Count each Window hosted by the current opaque bounding Surface - iNumWindows = 0; - for (int iwndo = iSurfaceFirst; iwndo <= iSurfaceLast; ++iwndo) { - if (state.dataSurface->Surface(iwndo).Class == SurfaceClass::Window) { - auto &wndo(state.dataSurface->Surface(iwndo)); - if (wndo.BaseSurfName == surf.Name) { - - // Error if window has multiplier > 1 since this causes incorrect illuminance calc - if (wndo.Multiplier > 1.0) { - ShowSevereError(state, - "Multiplier > 1.0 for window " + wndo.Name + - " not allowed since it is in a zone with DElight daylighting."); - ErrorsFound = true; - } - - // Error if window has a shading device (blind/shade/screen) since - // DElight cannot perform dynamic shading device deployment - if (wndo.HasShadeControl) { - ShowSevereError(state, - "Shading Device on window " + wndo.Name + - " dynamic control is not supported in a zone with DElight daylighting."); - ErrorsFound = true; - } + for (int spaceNum : zn.spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const iSurfaceFirst = thisSpace.HTSurfaceFirst; + int const iSurfaceLast = thisSpace.HTSurfaceLast; + for (int isurf = iSurfaceFirst; isurf <= iSurfaceLast; ++isurf) { + + auto &surf(state.dataSurface->Surface(isurf)); + + // Only process "opaque bounding" surface types + if ((surf.Class == SurfaceClass::Wall) || (surf.Class == SurfaceClass::Roof) || (surf.Class == SurfaceClass::Floor)) { + + // Get the Construction index for this Surface + iconstruct = surf.Construction; + + // Is this Surface exposed to the exterior? + if (surf.ExtSolar) { + // Get the index for the outside (i.e., 1st) Material Layer for this Construction + iMatlLayer = state.dataConstruction->Construct(iconstruct).LayerPoint(1); + // Get the outside visible reflectance of this material layer + // (since Construct(iconstruct)%ReflectVisDiffFront always appears to == 0.0) + rExtVisRefl = 1.0 - state.dataMaterial->Material(iMatlLayer).AbsorpVisible; + } else { + rExtVisRefl = 0.0; + } - // Loop through all Doppelganger Surface Names to ignore these Windows - lWndoIsDoppelganger = false; - for (auto &cfs : state.dataDaylightingData->DElightComplexFene) { + // Remove any blanks from the Surface Name for ease of input to DElight + cNameWOBlanks = ReplaceBlanksWithUnderscores(surf.Name); + print(delightInFile, + Format_907, + cNameWOBlanks, + surf.Azimuth, + surf.Tilt, + state.dataConstruction->Construct(iconstruct).ReflectVisDiffBack, + rExtVisRefl, + surf.Sides); + + // Write out the vertex coordinates for each vertex + int const iNumVertices = surf.Sides; // Counter for surface vertices + for (int ivert = 1; ivert <= iNumVertices; ++ivert) { + print(delightInFile, + Format_908, + surf.Vertex(ivert).x * M2FT, + surf.Vertex(ivert).y * M2FT, + surf.Vertex(ivert).z * M2FT); + } - // Is the current Window Surface a Doppelganger? - if (wndo.Name == cfs.wndwName) { - // Ignore this Doppelganger Window - lWndoIsDoppelganger = true; + // Count each Window hosted by the current opaque bounding Surface + iNumWindows = 0; + for (int iwndo = iSurfaceFirst; iwndo <= iSurfaceLast; ++iwndo) { + if (state.dataSurface->Surface(iwndo).Class == SurfaceClass::Window) { + auto &wndo(state.dataSurface->Surface(iwndo)); + if (wndo.BaseSurfName == surf.Name) { + + // Error if window has multiplier > 1 since this causes incorrect illuminance calc + if (wndo.Multiplier > 1.0) { + ShowSevereError(state, + "Multiplier > 1.0 for window " + wndo.Name + + " not allowed since it is in a zone with DElight daylighting."); + ErrorsFound = true; } - } // CFS object loop A - - if (!lWndoIsDoppelganger) { - ++iNumWindows; - } - - } // Surface hosts Window test - } // Window test - } // Window loop - - print(delightInFile, Format_909, iNumWindows); - - // If the current opaque bounding Surface hosts Windows, - // then write each hosted Window to the DElight input file - // and track the Window Construction type for later writing - if (iNumWindows > 0) { - for (int iwndo2 = iSurfaceFirst; iwndo2 <= iSurfaceLast; ++iwndo2) { - if (state.dataSurface->Surface(iwndo2).Class == SurfaceClass::Window) { - - auto &wndo2(state.dataSurface->Surface(iwndo2)); - - if (wndo2.BaseSurfName == surf.Name) { + // Error if window has a shading device (blind/shade/screen) since + // DElight cannot perform dynamic shading device deployment + if (wndo.HasShadeControl) { + ShowSevereError(state, + "Shading Device on window " + wndo.Name + + " dynamic control is not supported in a zone with DElight daylighting."); + ErrorsFound = true; + } // Loop through all Doppelganger Surface Names to ignore these Windows lWndoIsDoppelganger = false; - for (auto &cfs : state.dataDaylightingData->DElightComplexFene) { // Is the current Window Surface a Doppelganger? - if (wndo2.Name == cfs.wndwName) { + if (wndo.Name == cfs.wndwName) { // Ignore this Doppelganger Window lWndoIsDoppelganger = true; } @@ -436,112 +408,147 @@ namespace DElightManagerF { } // CFS object loop A if (!lWndoIsDoppelganger) { + ++iNumWindows; + } - // Track unique window construction types here for later writing to - // the library section of DElight input file - - // Get the Construction index for this Window Surface - iconstruct = wndo2.Construction; - - // Has the current Construction index been encountered before? - lWndoConstFound = false; - for (int iconst = 1; iconst <= iNumWndoConsts; ++iconst) { - if (iconstruct == iWndoConstIndexes(iconst)) lWndoConstFound = true; - } - if (!lWndoConstFound) { - ++iNumWndoConsts; - iWndoConstIndexes(iNumWndoConsts) = iconstruct; - } - - // Write this Window to the DElight input file - // Remove any blanks from the Window Surface Name for ease of input to DElight - cNameWOBlanks = ReplaceBlanksWithUnderscores(wndo2.Name); - print(delightInFile, Format_910, cNameWOBlanks, iconstruct + 10000, wndo2.Sides); - // Use WndoConstIndex + 10000 as the Glass Type Name - // to differentiate EPlus glass types within DElight - - // Write out the vertex coordinates for each vertex - int const iNumVertices = wndo2.Sides; // Counter for surface vertices - for (int ivert = 1; ivert <= iNumVertices; ++ivert) { - print(delightInFile, - Format_908, - wndo2.Vertex(ivert).x * M2FT, - wndo2.Vertex(ivert).y * M2FT, - wndo2.Vertex(ivert).z * M2FT); - } - } //! lWndoIsDoppelganger - } // Surface hosts Window2 test - } // Window2 Class test - } // Window2 loop - } // Hosted Windows test - - // Write the number of CFS hosted by the current Opaque Bounding Surface - iHostedCFS = 0; - - // Loop through the input CFS objects searching for a match to the current Opaque Bounding Surface - for (auto &cfs : state.dataDaylightingData->DElightComplexFene) { - - // Does the current Opaque Bounding Surface host the current CFS object? - if (surf.Name == cfs.surfName) { - // Count this hosted CFS - ++iHostedCFS; - } - } // CFS object loop 1 + } // Surface hosts Window test + } // Window test + } // Window loop + + print(delightInFile, Format_909, iNumWindows); + + // If the current opaque bounding Surface hosts Windows, + // then write each hosted Window to the DElight input file + // and track the Window Construction type for later writing + if (iNumWindows > 0) { + for (int iwndo2 = iSurfaceFirst; iwndo2 <= iSurfaceLast; ++iwndo2) { + if (state.dataSurface->Surface(iwndo2).Class == SurfaceClass::Window) { + + auto &wndo2(state.dataSurface->Surface(iwndo2)); + + if (wndo2.BaseSurfName == surf.Name) { + + // Loop through all Doppelganger Surface Names to ignore these Windows + lWndoIsDoppelganger = false; + + for (auto &cfs : state.dataDaylightingData->DElightComplexFene) { + + // Is the current Window Surface a Doppelganger? + if (wndo2.Name == cfs.wndwName) { + // Ignore this Doppelganger Window + lWndoIsDoppelganger = true; + } + + } // CFS object loop A + + if (!lWndoIsDoppelganger) { + + // Track unique window construction types here for later writing to + // the library section of DElight input file + + // Get the Construction index for this Window Surface + iconstruct = wndo2.Construction; + + // Has the current Construction index been encountered before? + lWndoConstFound = false; + for (int iconst = 1; iconst <= iNumWndoConsts; ++iconst) { + if (iconstruct == iWndoConstIndexes(iconst)) lWndoConstFound = true; + } + if (!lWndoConstFound) { + ++iNumWndoConsts; + iWndoConstIndexes(iNumWndoConsts) = iconstruct; + } + + // Write this Window to the DElight input file + // Remove any blanks from the Window Surface Name for ease of input to DElight + cNameWOBlanks = ReplaceBlanksWithUnderscores(wndo2.Name); + print(delightInFile, Format_910, cNameWOBlanks, iconstruct + 10000, wndo2.Sides); + // Use WndoConstIndex + 10000 as the Glass Type Name + // to differentiate EPlus glass types within DElight + + // Write out the vertex coordinates for each vertex + int const iNumVertices = wndo2.Sides; // Counter for surface vertices + for (int ivert = 1; ivert <= iNumVertices; ++ivert) { + print(delightInFile, + Format_908, + wndo2.Vertex(ivert).x * M2FT, + wndo2.Vertex(ivert).y * M2FT, + wndo2.Vertex(ivert).z * M2FT); + } + } //! lWndoIsDoppelganger + } // Surface hosts Window2 test + } // Window2 Class test + } // Window2 loop + } // Hosted Windows test + + // Write the number of CFS hosted by the current Opaque Bounding Surface + iHostedCFS = 0; + + // Loop through the input CFS objects searching for a match to the current Opaque Bounding Surface + for (auto &cfs : state.dataDaylightingData->DElightComplexFene) { + + // Does the current Opaque Bounding Surface host the current CFS object? + if (surf.Name == cfs.surfName) { + // Count this hosted CFS + ++iHostedCFS; + } + } // CFS object loop 1 - print(delightInFile, Format_911, iHostedCFS); + print(delightInFile, Format_911, iHostedCFS); - // Now write each of the hosted CFS data - // Loop through the input CFS objects searching for a match to the current Opaque Bounding Surface - for (auto &cfs : state.dataDaylightingData->DElightComplexFene) { + // Now write each of the hosted CFS data + // Loop through the input CFS objects searching for a match to the current Opaque Bounding Surface + for (auto &cfs : state.dataDaylightingData->DElightComplexFene) { - // Does the current Opaque Bounding Surface host the current CFS object? - if (surf.Name == cfs.surfName) { + // Does the current Opaque Bounding Surface host the current CFS object? + if (surf.Name == cfs.surfName) { - // Get the Doppelganger surface for this CFS - iDoppelganger = 0; - for (int iwndo3 = iSurfaceFirst; iwndo3 <= iSurfaceLast; ++iwndo3) { + // Get the Doppelganger surface for this CFS + iDoppelganger = 0; + for (int iwndo3 = iSurfaceFirst; iwndo3 <= iSurfaceLast; ++iwndo3) { - auto &wndo3(state.dataSurface->Surface(iwndo3)); + auto &wndo3(state.dataSurface->Surface(iwndo3)); - if (wndo3.Class == SurfaceClass::Window) { + if (wndo3.Class == SurfaceClass::Window) { - // Is the current Window Surface the Doppelganger for the current CFS? - if (wndo3.Name == cfs.wndwName) { - // Store the window surface index for future reference - iDoppelganger = iwndo3; + // Is the current Window Surface the Doppelganger for the current CFS? + if (wndo3.Name == cfs.wndwName) { + // Store the window surface index for future reference + iDoppelganger = iwndo3; + } } } - } - // Make sure that a valid Doppelganger surface exists - if (iDoppelganger > 0) { + // Make sure that a valid Doppelganger surface exists + if (iDoppelganger > 0) { - // Write the data for this hosted CFS - auto &doppelgangerSurf(state.dataSurface->Surface(iDoppelganger)); + // Write the data for this hosted CFS + auto &doppelgangerSurf(state.dataSurface->Surface(iDoppelganger)); - // Remove any blanks from the CFS Name for ease of input to DElight - cNameWOBlanks = ReplaceBlanksWithUnderscores(cfs.Name); - int const iNumVertices = doppelgangerSurf.Sides; // Counter for surface vertices - print(delightInFile, Format_915, cNameWOBlanks, cfs.ComplexFeneType, cfs.feneRota, iNumVertices); + // Remove any blanks from the CFS Name for ease of input to DElight + cNameWOBlanks = ReplaceBlanksWithUnderscores(cfs.Name); + int const iNumVertices = doppelgangerSurf.Sides; // Counter for surface vertices + print(delightInFile, Format_915, cNameWOBlanks, cfs.ComplexFeneType, cfs.feneRota, iNumVertices); - // Write out the vertex coordinates for each vertex - for (int ivert = 1; ivert <= iNumVertices; ++ivert) { - print(delightInFile, - Format_908, - doppelgangerSurf.Vertex(ivert).x * M2FT, - doppelgangerSurf.Vertex(ivert).y * M2FT, - doppelgangerSurf.Vertex(ivert).z * M2FT); + // Write out the vertex coordinates for each vertex + for (int ivert = 1; ivert <= iNumVertices; ++ivert) { + print(delightInFile, + Format_908, + doppelgangerSurf.Vertex(ivert).x * M2FT, + doppelgangerSurf.Vertex(ivert).y * M2FT, + doppelgangerSurf.Vertex(ivert).z * M2FT); + } } - } - // Register Error if there is no valid Doppelganger for current Complex Fenestration - if (iDoppelganger == 0) { - ShowSevereError(state, "No Doppelganger Window Surface found for Complex Fenestration =" + cfs.Name); - ErrorsFound = true; - } - } // The current Opaque Bounding Surface hosts the current CFS object? - } // CFS object loop 2 - } // Opaque Bounding Surface test - } // Zone Surface loop + // Register Error if there is no valid Doppelganger for current Complex Fenestration + if (iDoppelganger == 0) { + ShowSevereError(state, "No Doppelganger Window Surface found for Complex Fenestration =" + cfs.Name); + ErrorsFound = true; + } + } // The current Opaque Bounding Surface hosts the current CFS object? + } // CFS object loop 2 + } // Opaque Bounding Surface test + } + } // Zone Surface loop // Write ZONE REFERENCE POINTS print(delightInFile, Format_912, znDayl.TotalDaylRefPoints); diff --git a/src/EnergyPlus/DXCoils.cc b/src/EnergyPlus/DXCoils.cc index 56a07bb5d83..dc7e2f292a1 100644 --- a/src/EnergyPlus/DXCoils.cc +++ b/src/EnergyPlus/DXCoils.cc @@ -68,7 +68,6 @@ #include #include #include -#include #include #include #include @@ -93,6 +92,7 @@ #include #include #include +#include namespace EnergyPlus::DXCoils { @@ -7610,8 +7610,8 @@ void InitDXCoil(EnergyPlusData &state, int const DXCoilNum) // number of the cur if (state.dataDXCoils->DXCoil(DXCoilNum).IsSecondaryDXCoilInZone) { state.dataDXCoils->DXCoil(DXCoilNum).EvapInletWetBulb = PsyTwbFnTdbWPb(state, - state.dataHeatBalFanSys->ZT(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr), - state.dataHeatBalFanSys->ZoneAirHumRat(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr), + state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr).ZT, + state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr).ZoneAirHumRat, state.dataEnvrn->OutBaroPress, RoutineName); } @@ -9719,8 +9719,9 @@ void CalcDoe2DXCoil(EnergyPlusData &state, OutdoorWetBulb = state.dataEnvrn->OutWetBulbTemp; } if (state.dataDXCoils->DXCoil(DXCoilNum).IsSecondaryDXCoilInZone) { - OutdoorDryBulb = state.dataHeatBalFanSys->ZT(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); - OutdoorHumRat = state.dataHeatBalFanSys->ZoneAirHumRat(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); + auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); + OutdoorDryBulb = secZoneHB.ZT; + OutdoorHumRat = secZoneHB.ZoneAirHumRat; OutdoorWetBulb = state.dataDXCoils->DXCoil(DXCoilNum).EvapInletWetBulb; OutdoorPressure = state.dataEnvrn->OutBaroPress; } @@ -9739,10 +9740,11 @@ void CalcDoe2DXCoil(EnergyPlusData &state, CondInletTemp = OutdoorDryBulb; // Outdoor dry-bulb temp CompAmbTemp = OutdoorDryBulb; if (state.dataDXCoils->DXCoil(DXCoilNum).IsSecondaryDXCoilInZone) { - CondInletTemp = state.dataHeatBalFanSys->ZT(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); + auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); + CondInletTemp = secZoneHB.ZT; CompAmbTemp = CondInletTemp; // assumes compressor is in same location as secondary coil OutdoorDryBulb = CondInletTemp; - OutdoorHumRat = state.dataHeatBalFanSys->ZoneAirHumRat(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); + OutdoorHumRat = secZoneHB.ZoneAirHumRat; OutdoorWetBulb = state.dataDXCoils->DXCoil(DXCoilNum).EvapInletWetBulb; OutdoorPressure = state.dataEnvrn->OutBaroPress; } @@ -11441,16 +11443,18 @@ void CalcDXHeatingCoil(EnergyPlusData &state, OutdoorWetBulb = state.dataLoopNodes->Node(state.dataDXCoils->DXCoil(DXCoilNum).CondenserInletNodeNum(1)).OutAirWetBulb; } if (state.dataDXCoils->DXCoil(DXCoilNum).IsSecondaryDXCoilInZone) { - OutdoorDryBulb = state.dataHeatBalFanSys->ZT(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); - OutdoorHumRat = state.dataHeatBalFanSys->ZoneAirHumRat(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); + auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); + OutdoorDryBulb = secZoneHB.ZT; + OutdoorHumRat = secZoneHB.ZoneAirHumRat; OutdoorWetBulb = state.dataDXCoils->DXCoil(DXCoilNum).EvapInletWetBulb; OutdoorPressure = state.dataEnvrn->OutBaroPress; CompAmbTemp = OutdoorDryBulb; } } } else if (state.dataDXCoils->DXCoil(DXCoilNum).IsSecondaryDXCoilInZone) { - OutdoorDryBulb = state.dataHeatBalFanSys->ZT(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); - OutdoorHumRat = state.dataHeatBalFanSys->ZoneAirHumRat(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); + auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); + OutdoorDryBulb = secZoneHB.ZT; + OutdoorHumRat = secZoneHB.ZoneAirHumRat; OutdoorWetBulb = state.dataDXCoils->DXCoil(DXCoilNum).EvapInletWetBulb; OutdoorPressure = state.dataEnvrn->OutBaroPress; CompAmbTemp = OutdoorDryBulb; @@ -11940,15 +11944,17 @@ void CalcMultiSpeedDXCoil(EnergyPlusData &state, } CompAmbTemp = OutdoorDryBulb; if (state.dataDXCoils->DXCoil(DXCoilNum).IsSecondaryDXCoilInZone) { - OutdoorDryBulb = state.dataHeatBalFanSys->ZT(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); - OutdoorHumRat = state.dataHeatBalFanSys->ZoneAirHumRat(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); + auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); + OutdoorDryBulb = secZoneHB.ZT; + OutdoorHumRat = secZoneHB.ZoneAirHumRat; OutdoorWetBulb = state.dataDXCoils->DXCoil(DXCoilNum).EvapInletWetBulb; OutdoorPressure = state.dataEnvrn->OutBaroPress; CompAmbTemp = OutdoorDryBulb; } } else if (state.dataDXCoils->DXCoil(DXCoilNum).IsSecondaryDXCoilInZone) { - OutdoorDryBulb = state.dataHeatBalFanSys->ZT(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); - OutdoorHumRat = state.dataHeatBalFanSys->ZoneAirHumRat(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); + auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); + OutdoorDryBulb = secZoneHB.ZT; + OutdoorHumRat = secZoneHB.ZoneAirHumRat; OutdoorWetBulb = state.dataDXCoils->DXCoil(DXCoilNum).EvapInletWetBulb; OutdoorPressure = state.dataEnvrn->OutBaroPress; CompAmbTemp = OutdoorDryBulb; @@ -13181,14 +13187,16 @@ void CalcMultiSpeedDXCoilCooling(EnergyPlusData &state, OutdoorWetBulb = PsyTwbFnTdbWPb(state, OutdoorDryBulb, OutdoorHumRat, OutdoorPressure, RoutineName); } if (state.dataDXCoils->DXCoil(DXCoilNum).IsSecondaryDXCoilInZone) { - OutdoorDryBulb = state.dataHeatBalFanSys->ZT(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); - OutdoorHumRat = state.dataHeatBalFanSys->ZoneAirHumRat(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); + auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); + OutdoorDryBulb = secZoneHB.ZT; + OutdoorHumRat = secZoneHB.ZoneAirHumRat; OutdoorWetBulb = state.dataDXCoils->DXCoil(DXCoilNum).EvapInletWetBulb; OutdoorPressure = state.dataEnvrn->OutBaroPress; } } else if (state.dataDXCoils->DXCoil(DXCoilNum).IsSecondaryDXCoilInZone) { - OutdoorDryBulb = state.dataHeatBalFanSys->ZT(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); - OutdoorHumRat = state.dataHeatBalFanSys->ZoneAirHumRat(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); + auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); + OutdoorDryBulb = secZoneHB.ZT; + OutdoorHumRat = secZoneHB.ZoneAirHumRat; OutdoorWetBulb = state.dataDXCoils->DXCoil(DXCoilNum).EvapInletWetBulb; OutdoorPressure = state.dataEnvrn->OutBaroPress; } else { @@ -14098,14 +14106,16 @@ void CalcMultiSpeedDXCoilHeating(EnergyPlusData &state, OutdoorHumRat = state.dataLoopNodes->Node(state.dataDXCoils->DXCoil(DXCoilNum).CondenserInletNodeNum(1)).HumRat; } if (state.dataDXCoils->DXCoil(DXCoilNum).IsSecondaryDXCoilInZone) { - OutdoorDryBulb = state.dataHeatBalFanSys->ZT(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); - OutdoorHumRat = state.dataHeatBalFanSys->ZoneAirHumRat(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); + auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); + OutdoorDryBulb = secZoneHB.ZT; + OutdoorHumRat = secZoneHB.ZoneAirHumRat; // OutdoorWetBulb = DXCoil( DXCoilNum ).EvapInletWetBulb; OutdoorPressure = state.dataEnvrn->OutBaroPress; } } else if (state.dataDXCoils->DXCoil(DXCoilNum).IsSecondaryDXCoilInZone) { - OutdoorDryBulb = state.dataHeatBalFanSys->ZT(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); - OutdoorHumRat = state.dataHeatBalFanSys->ZoneAirHumRat(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); + auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); + OutdoorDryBulb = secZoneHB.ZT; + OutdoorHumRat = secZoneHB.ZoneAirHumRat; // OutdoorWetBulb = DXCoil( DXCoilNum ).EvapInletWetBulb; OutdoorPressure = state.dataEnvrn->OutBaroPress; } else { @@ -16850,6 +16860,7 @@ void CalcSecondaryDXCoils(EnergyPlusData &state, int const DXCoilNum) EvapAirMassFlow = 0.0; if (state.dataDXCoils->DXCoil(DXCoilNum).IsSecondaryDXCoilInZone) { + auto &secZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); // Select the correct unit type switch (state.dataDXCoils->DXCoil(DXCoilNum).DXCoilType_Num) { case CoilDX_CoolingSingleSpeed: @@ -16876,8 +16887,8 @@ void CalcSecondaryDXCoils(EnergyPlusData &state, int const DXCoilNum) return; } state.dataDXCoils->DXCoil(DXCoilNum).SecCoilTotalHeatRemovalRate = -TotalHeatRemovalRate; // +DXCoil( DXCoilNum ).DefrostPower; - EvapInletDryBulb = state.dataHeatBalFanSys->ZT(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); - EvapInletHumRat = state.dataHeatBalFanSys->ZoneAirHumRat(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); + EvapInletDryBulb = secZoneHB.ZT; + EvapInletHumRat = secZoneHB.ZoneAirHumRat; RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, EvapInletDryBulb, EvapInletHumRat); EvapAirMassFlow = RhoAir * state.dataDXCoils->DXCoil(DXCoilNum).SecCoilAirFlow; ; @@ -16936,8 +16947,8 @@ void CalcSecondaryDXCoils(EnergyPlusData &state, int const DXCoilNum) state.dataDXCoils->DXCoil(DXCoilNum).SecCoilSHR = SHR; } break; case CoilDX_MultiSpeedHeating: { - EvapInletDryBulb = state.dataHeatBalFanSys->ZT(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); - EvapInletHumRat = state.dataHeatBalFanSys->ZoneAirHumRat(state.dataDXCoils->DXCoil(DXCoilNum).SecZonePtr); + EvapInletDryBulb = secZoneHB.ZT; + EvapInletHumRat = secZoneHB.ZoneAirHumRat; RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, EvapInletDryBulb, EvapInletHumRat); MSSpeedRatio = state.dataDXCoils->DXCoil(DXCoilNum).MSSpeedRatio; MSCycRatio = state.dataDXCoils->DXCoil(DXCoilNum).MSCycRatio; diff --git a/src/EnergyPlus/DataHeatBalFanSys.hh b/src/EnergyPlus/DataHeatBalFanSys.hh index a3afe466985..f19cca58c6f 100644 --- a/src/EnergyPlus/DataHeatBalFanSys.hh +++ b/src/EnergyPlus/DataHeatBalFanSys.hh @@ -65,11 +65,8 @@ namespace DataHeatBalFanSys { // -only module should be available to other modules and routines. // Thus, all variables in this module must be PUBLIC. - // MODULE PARAMETER DEFINITIONS: constexpr Real64 MaxRadHeatFlux = 4000.0; // [W/m2] max limit for radiant heat flux at a surface due to HVAC equipment - // Controls for PredictorCorrector - enum class PredictorCorrectorCtrl { Invalid = -1, @@ -106,80 +103,9 @@ struct HeatBalFanSysData : BaseGlobalStruct Array1D ZoneQSteamBaseboardToPerson; // Sum of radiant gains to people from steam baseboard heaters Array1D ZoneQElecBaseboardToPerson; // Sum of radiant gains to people from electric baseboard heaters Array1D ZoneQCoolingPanelToPerson; // Sum of radiant losses to people from cooling panels + // Zone air drybulb conditions variables - Array1D ZTAV; // Zone Air Temperature Averaged over the Zone Time step - Array1D MAT; // MEAN AIR TEMPERATURE (C) Array1D TempTstatAir; // temperature of air near the thermo stat - Array1D ZT; // Zone Air Temperature Averaged over the System Time Increment - Array1D XMAT; // TEMPORARY ZONE TEMPERATURE TO TEST CONVERGENCE - Array1D XM2T; - Array1D XM3T; - Array1D XM4T; - Array1D DSXMAT; // Down Stepped MAT history storage - Array1D DSXM2T; // Down Stepped MAT history storage - Array1D DSXM3T; // Down Stepped MAT history storage - Array1D DSXM4T; // Down Stepped MAT history storage - Array1D XMPT; // Zone air temperature at previous time step - - Array1D ZTAVComf; // Zone Air Temperature Averaged over the Zone Time step used - // in thermal comfort models (currently Fang model only) - Array1D ZoneAirHumRatAvgComf; // AIR Humidity Ratio averaged over the zone time - // step used in thermal comfort models (currently Fang model only) - - // Zone Air moisture conditions variables - Array1D ZoneAirHumRatAvg; // AIR Humidity Ratio averaged over the zone time step - Array1D ZoneAirHumRat; // AIR Humidity Ratio - Array1D WZoneTimeMinus1; // Humidity ratio history terms for 3rd order derivative - Array1D WZoneTimeMinus2; // Time Minus 2 Zone Time Steps Term - Array1D WZoneTimeMinus3; // Time Minus 3 Zone Time Steps Term - Array1D WZoneTimeMinus4; // Time Minus 4 Zone Time Steps Term - Array1D DSWZoneTimeMinus1; // DownStepped Humidity ratio history terms for 3rd order derivative - Array1D DSWZoneTimeMinus2; // DownStepped Time Minus 2 Zone Time Steps Term - Array1D DSWZoneTimeMinus3; // DownStepped Time Minus 3 Zone Time Steps Term - Array1D DSWZoneTimeMinus4; // DownStepped Time Minus 4 Zone Time Steps Term - Array1D WZoneTimeMinusP; // Humidity ratio history terms at previous time step - - Array1D ZoneAirHumRatTemp; // Temp zone air humidity ratio at time plus 1 - Array1D WZoneTimeMinus1Temp; // Zone air humidity ratio at previous timestep - Array1D WZoneTimeMinus2Temp; // Zone air humidity ratio at timestep T-2 - Array1D WZoneTimeMinus3Temp; // Zone air humidity ratio at timestep T-3 - Array1D ZoneAirHumRatOld; // Last Time Steps Zone AIR Humidity Ratio - - Array1D MCPI; // INFILTRATION MASS FLOW * AIR SPECIFIC HEAT - Array1D MCPTI; // INFILTRATION MASS FLOW * AIR CP * AIR TEMPERATURE - Array1D MCPV; // VENTILATION MASS FLOW * AIR SPECIFIC HEAT - Array1D MCPTV; // VENTILATION MASS FLOW * AIR CP * AIR TEMPERATURE - Array1D MCPM; // Mixing MASS FLOW * AIR SPECIFIC HEAT - Array1D MCPTM; // Mixing MASS FLOW * AIR CP * AIR TEMPERATURE - Array1D MCPE; // EARTHTUBE MASS FLOW * AIR SPECIFIC HEAT - Array1D EAMFL; // OUTDOOR AIR MASS FLOW for EarthTube - Array1D EAMFLxHumRat; // OUTDOOR AIR MASS FLOW * Humidity Ratio for EarthTube (water vapor mass flow) - Array1D MCPTE; // EARTHTUBE MASS FLOW * AIR CP * AIR TEMPERATURE - Array1D MCPC; // COOLTOWER MASS FLOW * AIR SPECIFIC HEAT - Array1D CTMFL; // OUTDOOR AIR MASS FLOW for cooltower - Array1D MCPTC; // COOLTOWER MASS FLOW * AIR CP * AIR TEMPERATURE - Array1D ThermChimAMFL; // OUTDOOR AIR MASS FLOW for THERMALCHIMNEY - Array1D MCPTThermChim; // THERMALCHIMNEY MASS FLOW * AIR SPECIFIC HEAT - Array1D MCPThermChim; // THERMALCHIMNEY MASS FLOW * AIR CP * AIR TEMPERATURE - Array1D ZoneLatentGain; // Latent Energy from each Zone (People, equipment) - Array1D ZoneLatentGainExceptPeople; // Added for hybrid model -- Latent Energy from each Zone (equipment) - Array1D OAMFL; // OUTDOOR AIR MASS FLOW (kg/s) for infiltration - Array1D VAMFL; // OUTDOOR AIR MASS FLOW (kg/s) for ventilation - Array1D NonAirSystemResponse; // Convective heat addition rate from non forced air - // equipment such as baseboards plus heat from lights to - Array1D SysDepZoneLoads; // Convective heat addition or subtraction rate from sources that - // depend on what is happening with the HVAC system. Such as: - // heat gain from lights to return air when return flow = 0; heat gain - // from air flow windows to return air when return air flow = 0; - // and heat removed by return air from refrigeration cases when - // return air flow = 0. - Array1D SysDepZoneLoadsLagged; // SysDepZoneLoads saved to be added to zone heat balance next - // HVAC time step - Array1D MDotCPOA; // Airbalance MASS FLOW * AIR SPECIFIC HEAT used at Air Balance Method = Quadrature in the ZoneAirBalance:OutdoorAir - Array1D MDotOA; // Airbalance MASS FLOW rate used at Air Balance Method = Quadrature in the ZoneAirBalance:OutdoorAir - - Array1D MixingMassFlowZone; // Mixing MASS FLOW (kg/s) - Array1D MixingMassFlowXHumRat; // Mixing MASS FLOW * Humidity Ratio Array1D_bool ZoneMassBalanceFlag; // zone mass flow balance flag Array1D_bool ZoneInfiltrationFlag; // Zone Infiltration flag @@ -215,12 +141,6 @@ struct HeatBalFanSysData : BaseGlobalStruct Array1D RadSysToHBTinCoef; // Outside heat balance coefficient that modifies Toutside Array1D RadSysToHBQsrcCoef; // Outside heat balance coefficient that modifies source/sink - // Moisture variables to carry info from HB to the Zone Temp Predictor-Corrector for Fan System - Array1D SumHmAW; // SUM OF ZONE AREA*Moist CONVECTION COEFF*INSIDE Humidity Ratio - Array1D SumHmARa; // SUM OF ZONE AREA*Moist CONVECTION COEFF*Rho Air - Array1D SumHmARaW; // SUM OF ZONE AREA*Moist CONVECTION COEFF*Rho Air* Inside Humidity Ration - Array1D SumHmARaZ; - Array1D TempZoneThermostatSetPoint; Array1D AdapComfortCoolingSetPoint; Array1D ZoneThermostatSetPointHi; @@ -228,12 +148,8 @@ struct HeatBalFanSysData : BaseGlobalStruct Array1D ZoneThermostatSetPointHiAver; Array1D ZoneThermostatSetPointLoAver; - Array1D LoadCorrectionFactor; // PH 3/3/04 + EPVector LoadCorrectionFactor; // PH 3/3/04 - Array1D AIRRAT; // "air power capacity" PH 3/5/04 - Array1D ZTM1; // zone air temperature at previous timestep - Array1D ZTM2; // zone air temperature at timestep T-2 - Array1D ZTM3; // zone air temperature at previous T-3 // Hybrid Modeling Array1D PreviousMeasuredZT1; // Measured zone air temperature at previous timestep1 Array1D PreviousMeasuredZT2; // Measured zone air temperature at previous timestep2 @@ -241,13 +157,6 @@ struct HeatBalFanSysData : BaseGlobalStruct Array1D PreviousMeasuredHumRat1; // Hybrid model zone humidity ratio at previous timestep Array1D PreviousMeasuredHumRat2; // Hybrid model zone humidity ratio at previous timestep Array1D PreviousMeasuredHumRat3; // Hybrid model zone humidity ratio at previous timestep - // Exact and Euler solutions - Array1D ZoneTMX; // TEMPORARY ZONE TEMPERATURE TO TEST CONVERGENCE in Exact and Euler method - Array1D ZoneTM2; // TEMPORARY ZONE TEMPERATURE at timestep t-2 in Exact and Euler method - Array1D ZoneT1; // Zone temperature at the previous time step used in Exact and Euler method - Array1D ZoneWMX; // TEMPORARY ZONE TEMPERATURE TO TEST CONVERGENCE in Exact and Euler method - Array1D ZoneWM2; // TEMPORARY ZONE TEMPERATURE at timestep t-2 in Exact and Euler method - Array1D ZoneW1; // Zone temperature at the previous time step used in Exact and Euler method EPVector TempControlType; EPVector TempControlTypeRpt; EPVector ComfortControlType; diff --git a/src/EnergyPlus/DataHeatBalance.cc b/src/EnergyPlus/DataHeatBalance.cc index f0f54d5747b..09c62948bb3 100644 --- a/src/EnergyPlus/DataHeatBalance.cc +++ b/src/EnergyPlus/DataHeatBalance.cc @@ -57,9 +57,11 @@ #include #include #include +#include #include #include #include +#include #include namespace EnergyPlus::DataHeatBalance { @@ -97,6 +99,49 @@ using DataBSDFWindow::BSDFWindowInputStruct; // Functions +Real64 SpaceData::sumHATsurf(EnergyPlusData &state) +{ + // PURPOSE OF THIS FUNCTION: + // This function calculates the space sum of Hc*Area*Tsurf. + + Real64 sumHATsurf = 0.0; + + for (int surfNum = this->HTSurfaceFirst; surfNum <= this->HTSurfaceLast; ++surfNum) { + Real64 Area = state.dataSurface->Surface(surfNum).Area; + + if (state.dataSurface->Surface(surfNum).Class == DataSurfaces::SurfaceClass::Window) { + if (state.dataSurface->SurfWinDividerArea(surfNum) > 0.0) { + if (ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(surfNum))) { + // The area is the shade or blind area = sum of the glazing area and the divider area (which is zero if no divider) + Area += state.dataSurface->SurfWinDividerArea(surfNum); + } else { + // Window divider contribution (only for window with divider and no interior shade or blind) + sumHATsurf += state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataSurface->SurfWinDividerArea(surfNum) * + (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivIn(surfNum)) * state.dataSurface->SurfWinDividerTempIn(surfNum); + } + } + + if (state.dataSurface->SurfWinFrameArea(surfNum) > 0.0) { + // Window frame contribution + sumHATsurf += state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataSurface->SurfWinFrameArea(surfNum) * + (1.0 + state.dataSurface->SurfWinProjCorrFrIn(surfNum)) * state.dataSurface->SurfWinFrameTempIn(surfNum); + } + } + + sumHATsurf += state.dataHeatBalSurf->SurfHConvInt(surfNum) * Area * state.dataHeatBalSurf->SurfTempInTmp(surfNum); + } + + return sumHATsurf; +} + +Real64 ZoneData::sumHATsurf(EnergyPlusData &state) +{ + Real64 sumHATsurf = 0.0; + for (int spaceNum : this->spaceIndexes) { + sumHATsurf += state.dataHeatBal->space(spaceNum).sumHATsurf(state); + } + return sumHATsurf; +} void ZoneData::SetOutBulbTempAt(EnergyPlusData &state) { // SUBROUTINE INFORMATION: @@ -158,6 +203,96 @@ void ZoneData::SetWindDirAt(Real64 const fac) WindDir = fac; } +void AirReportVars::setUpOutputVars(EnergyPlusData &state, std::string_view prefix, std::string_view name) +{ + SetupOutputVariable(state, + format("{} Mean Air Temperature", prefix), + OutputProcessor::Unit::C, + this->MeanAirTemp, + OutputProcessor::SOVTimeStepType::Zone, + OutputProcessor::SOVStoreType::Average, + name); + SetupOutputVariable(state, + format("{} Operative Temperature", prefix), + OutputProcessor::Unit::C, + this->OperativeTemp, + OutputProcessor::SOVTimeStepType::Zone, + OutputProcessor::SOVStoreType::Average, + name); + SetupOutputVariable(state, + format("{} Mean Air Dewpoint Temperature", prefix), + OutputProcessor::Unit::C, + this->MeanAirDewPointTemp, + OutputProcessor::SOVTimeStepType::Zone, + OutputProcessor::SOVStoreType::Average, + name); + SetupOutputVariable(state, + format("{} Mean Air Humidity Ratio", prefix), + OutputProcessor::Unit::kgWater_kgDryAir, + this->MeanAirHumRat, + OutputProcessor::SOVTimeStepType::Zone, + OutputProcessor::SOVStoreType::Average, + name); + SetupOutputVariable(state, + format("{} Air Heat Balance Internal Convective Heat Gain Rate", prefix), + OutputProcessor::Unit::W, + this->SumIntGains, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + SetupOutputVariable(state, + format("{} Air Heat Balance Surface Convection Rate", prefix), + OutputProcessor::Unit::W, + this->SumHADTsurfs, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + SetupOutputVariable(state, + format("{} Air Heat Balance Interzone Air Transfer Rate", prefix), + OutputProcessor::Unit::W, + this->SumMCpDTzones, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + SetupOutputVariable(state, + format("{} Air Heat Balance Outdoor Air Transfer Rate", prefix), + OutputProcessor::Unit::W, + this->SumMCpDtInfil, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + SetupOutputVariable(state, + format("{} Air Heat Balance System Air Transfer Rate", prefix), + OutputProcessor::Unit::W, + this->SumMCpDTsystem, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + SetupOutputVariable(state, + format("{} Air Heat Balance System Convective Heat Gain Rate", prefix), + OutputProcessor::Unit::W, + this->SumNonAirSystem, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + SetupOutputVariable(state, + format("{} Air Heat Balance Air Energy Storage Rate", prefix), + OutputProcessor::Unit::W, + this->CzdTdt, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + if (state.dataGlobal->DisplayAdvancedReportVariables) { + SetupOutputVariable(state, + format("{} Air Heat Balance Deviation Rate", prefix), + OutputProcessor::Unit::W, + this->imBalance, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + } +} + void SetZoneOutBulbTempAt(EnergyPlusData &state) { for (auto &zone : state.dataHeatBal->Zone) { diff --git a/src/EnergyPlus/DataHeatBalance.hh b/src/EnergyPlus/DataHeatBalance.hh index 34c04e0732c..5e91b5ef15b 100644 --- a/src/EnergyPlus/DataHeatBalance.hh +++ b/src/EnergyPlus/DataHeatBalance.hh @@ -509,6 +509,7 @@ namespace DataHeatBalance { Real64 Volume = DataGlobalConstants::AutoCalculate; // Volume entered by user [m3] or calculated Real64 ExtGrossWallArea = 0.0; // Exterior Wall Area for Zone (Gross) Real64 ExteriorTotalSurfArea = 0.0; // Total surface area of all exterior surfaces for Zone + int SystemZoneNodeNumber = 0; // This is the zone or space node number for the system for a controlled zone }; struct SpaceData : ZoneSpaceData @@ -522,8 +523,10 @@ namespace DataHeatBalance { Real64 calcFloorArea = 0.0; // Calculated floor area used for this space Real64 floorArea = 0.0; // Floor area used for this space bool hasFloor = false; // Has "Floor" surface - Real64 extWindowArea = 0.0; // Exterior Window Area for Zone - Real64 totalSurfArea = 0.0; // Total surface area for Zone + Real64 fracZoneFloorArea = 0.0; // fraction of total floor area for all spaces in zone + Real64 fracZoneVolume = 0.0; // fraction of total volume for all spaces in zone + Real64 extWindowArea = 0.0; // Exterior Window Area for space + Real64 totalSurfArea = 0.0; // Total surface area for space int radiantEnclosureNum = 0; // Radiant exchange enclosure this space belongs to int solarEnclosureNum = 0; // Solar distribution enclosure this space belongs to Real64 totOccupants = 0.0; // total design occupancy (sum of NumberOfPeople for the space People objects, not multiplied) @@ -532,6 +535,33 @@ namespace DataHeatBalance { bool isRemainderSpace = false; // True if this space is auto-generated "-Remainder" space std::vector otherEquipFuelTypeNums; // List of fuel types used by other equipment in this space std::vector otherEquipFuelTypeNames; // List of fuel types used by other equipment in this space + + // Pointers to Surface Data Structure + // |AllSurfF |AllSurfL + // | |HTSurfF |HTSurfL + // | |OpaqOrWinMassSurfF |OpaqOrWinSurfL | + // | |OpaqOrIntMassSurfF |OpaqOrIntMassSurfL | + // | | ||WindowSurfF |WindowSurfL | + // | | || ||DomeF |DomeL + // {[ SurfAir ] [( SurfOpaqOrIntMass )( SurfWinOrTDDDiffuser )( TDDDome )]} + // HTSurfaceFirst == OpaqOrWinMassSurfaceFirst == OpaqOrIntMassSurfaceFirst + // WindowSurfaceFirst == OpaqOrIntMassSurfaceLast + 1 + // TDDDomeFirst == OpaqOrWinSurfaceLast + 1 == WindowSurfaceLast + 1 + // AllSurfaceLast == HTSurfaceLast = TDDDomeLast + int AllSurfaceFirst = 0; // First surface in space including air boundaries + int AllSurfaceLast = -1; // Last surface in space including air boundaries + int HTSurfaceFirst = 0; // First Heat Transfer Surface in space + int HTSurfaceLast = -1; // Last Heat Transfer Surface in space + int OpaqOrIntMassSurfaceFirst = 0; // First Opaque or Interior Mass Heat Transfer Surface (including opaque doors) in space + int OpaqOrIntMassSurfaceLast = -1; // Last Opaque or Interior Mass Heat Transfer Surface (including opaque doors) in space + int WindowSurfaceFirst = 0; // First Window Heat Transfer Surface in space + int WindowSurfaceLast = -1; // Last Window Heat Transfer Surface in space + int OpaqOrWinSurfaceFirst = 0; // First opaque (including IntMass) or window (non TDD Dome) Surface in space + int OpaqOrWinSurfaceLast = -1; // Last opaque (including IntMass) or window (non TDD Dome) Surface in space + int TDDDomeFirst = 0; // First TDD Dome Surface in space + int TDDDomeLast = -1; // Last TDD Dome Surface in space + + Real64 sumHATsurf(EnergyPlusData &state); }; struct SpaceListData @@ -622,36 +652,14 @@ namespace DataHeatBalance { Real64 ExteriorTotalGroundSurfArea = 0.0; // Total surface area of all surfaces for Zone with ground contact Real64 ExtGrossGroundWallArea = 0.0; // Ground contact Wall Area for Zone (Gross) Real64 ExtGrossGroundWallArea_Multiplied = 0.0; // Ground contact Wall Area for Zone (Gross) with multipliers - int SystemZoneNodeNumber = 0; // This is the zone node number for the system for a controlled zone bool IsControlled = false; // True when this is a controlled zone. bool IsSupplyPlenum = false; // True when this zone is a supply plenum bool IsReturnPlenum = false; // True when this zone is a return plenum int PlenumCondNum = 0; // Supply or return plenum conditions number, 0 if this is not a plenum zone int TempControlledZoneIndex = 0; // this is the index number for TempControlledZone structure for lookup - // Pointers to Surface Data Structure - // |AllSurfF |AllSurfL - // | |HTSurfF |HTSurfL - // | |OpaqOrWinMassSurfF |OpaqOrWinSurfL | - // | |OpaqOrIntMassSurfF |OpaqOrIntMassSurfL | - // | | ||WindowSurfF |WindowSurfL | - // | | || ||DomeF |DomeL - // {[ SurfAir ] [( SurfOpaqOrIntMass )( SurfWinOrTDDDiffuser )( TDDDome )]} - // HTSurfaceFirst == OpaqOrWinMassSurfaceFirst == OpaqOrIntMassSurfaceFirst - // WindowSurfaceFirst == OpaqOrIntMassSurfaceLast + 1 - // TDDDomeFirst == OpaqOrWinSurfaceLast + 1 == WindowSurfaceLast + 1 - // AllSurfaceLast == HTSurfaceLast = TDDDomeLast - int AllSurfaceFirst = 0; // First surface in zone including air boundaries - int AllSurfaceLast = -1; // Last surface in zone including air boundaries - int HTSurfaceFirst = 0; // First Heat Transfer Surface in Zone - int HTSurfaceLast = -1; // Last Heat Transfer Surface in Zone - int OpaqOrIntMassSurfaceFirst = 0; // First Opaque or Interior Mass Heat Transfer Surface (including opaque doors) in Zone - int OpaqOrIntMassSurfaceLast = -1; // Last Opaque or Interior Mass Heat Transfer Surface (including opaque doors) in Zone - int WindowSurfaceFirst = 0; // First Window Heat Transfer Surface in Zone - int WindowSurfaceLast = -1; // Last Window Heat Transfer Surface in Zone - int OpaqOrWinSurfaceFirst = 0; // First opaque (including IntMass) or window (non TDD Dome) Surface in Zone - int OpaqOrWinSurfaceLast = -1; // Last opaque (including IntMass) or window (non TDD Dome) Surface in Zone - int TDDDomeFirst = 0; // First TDD Dome Surface in Zone - int TDDDomeLast = -1; // Last TDD Dome Surface in Zone + int humidityControlZoneIndex = 0; // this is the index number for HumidityControlZone structure for lookup + int AllSurfaceFirst = 0; // First surface in zone including air boundaries + int AllSurfaceLast = -1; // Last surface in zone including air boundaries int InsideConvectionAlgo = ConvectionConstants::HcInt_ASHRAESimple; // Ref: appropriate values for Inside Convection solution int NumSurfaces = 0; // Number of surfaces for this zone int NumSubSurfaces = 0; // Number of subsurfaces for this zone (windows, doors, tdd dome and diffusers) @@ -684,8 +692,7 @@ namespace DataHeatBalance { bool WindDirEMSOverrideOn = false; // if true, EMS is calling to override the surface's outside wind direction Real64 WindDirEMSOverrideValue = 0.0; // value to use for EMS override of the surface's outside wind speed - bool HasLinkedOutAirNode = false; // true if an OutdoorAir::Node is linked to the surface - int LinkedOutAirNode = 0; // Index of the an OutdoorAir:Node + int LinkedOutAirNode = 0; // Index of the an OutdoorAir:Node,, zero if none bool isPartOfTotalArea = true; // Count the zone area when determining the building total floor area bool isNominalOccupied = false; // has occupancy nominally specified @@ -759,6 +766,8 @@ namespace DataHeatBalance { void SetWindSpeedAt(EnergyPlusData &state, Real64 fac); void SetWindDirAt(Real64 fac); + + Real64 sumHATsurf(EnergyPlusData &state); }; struct ZoneListData @@ -1180,6 +1189,7 @@ namespace DataHeatBalance { Real64 EffAngle = 0.0; // Effective angle [degree] Real64 DH = 0.0; // Height difference [m] Real64 DiscCoef = 0.0; // Discharge coefficient + Real64 MCP = 0.0; // Product of mass flow rate and Cp }; struct ZoneAirBalanceData @@ -1235,6 +1245,7 @@ namespace DataHeatBalance { int NumRefDoorConnections = 0; bool EMSSimpleMixingOn = false; // EMS actuating ventilation flow rate if .TRUE. bool RefDoorMixFlag = false; // Refrigeration door mixing within zone + bool ReportFlag = false; // TRUE when Mixing or Cross Mixing is active based on controls Real64 EMSimpleMixingFlowRate = 0.0; // Value EMS is directing to use for override Array1D_bool EMSRefDoorMixingOn; Array1D EMSRefDoorFlowRate; @@ -1677,6 +1688,8 @@ namespace DataHeatBalance { Real64 OABalanceFanElec = 0.0; // Fan Electricity {W} due to OA air balance Real64 SumEnthalpyM = 0.0; // Zone sum of EnthalpyM Real64 SumEnthalpyH = 0.0; // Zone sum of EnthalpyH + + void setUpOutputVars(EnergyPlusData &state, std::string_view prefix, std::string_view name); }; struct ZonePreDefRepType @@ -1939,19 +1952,6 @@ namespace DataHeatBalance { Real64 SumToutMinusTSup = 0.0; // Denominator for zone-level sensible heat index (SHI) }; - struct latentReportVariables - { - Real64 ZoneLTLoadHeatEnergy = 0.0; // latent heating energy [J] - Real64 ZoneLTLoadCoolEnergy = 0.0; // latent cooling energy [J] - Real64 ZoneLTLoadHeatRate = 0.0; // latent heating rate [W] - Real64 ZoneLTLoadCoolRate = 0.0; // latent cooling rate [W] - Real64 ZoneSensibleHeatRatio = 0.0; // zone load SHR [] - Real64 ZoneVaporPressureDifference = 0.0; // vapor pressure depression [Pa] - Real64 ZoneMoisturePredictedRate = 0.0; - Real64 ZoneMoisturePredictedHumSPRate = 0.0; // Predicted latent load to humidification setpoint (unmultiplied) - Real64 ZoneMoisturePredictedDehumSPRate = 0.0; // Predicted latent load to dehumidification setpoint (unmultiplied) - }; - // Functions void SetZoneOutBulbTempAt(EnergyPlusData &state); @@ -2048,6 +2048,9 @@ struct HeatBalanceData : BaseGlobalStruct Real64 CondFDRelaxFactorInput = 1.0; // Relaxation factor, for looping across all the surfaces, user input value DataHeatBalance::SolutionAlgo ZoneAirSolutionAlgo = DataHeatBalance::SolutionAlgo::ThirdOrder; // ThirdOrderBackwardDifference, AnalyticalSolution, and EulerMethod + bool doSpaceHeatBalanceSizing = false; // Do space heat balance during sizing + bool doSpaceHeatBalanceSimulation = false; // Do space heat balance during simulation + bool doSpaceHeatBalance = false; // Do space heat balance currently bool OverrideZoneAirSolutionAlgo = false; // Override the zone air solution algorithm in PerformancePrecisionTradeoffs Real64 BuildingRotationAppendixG = 0.0; // Building Rotation for Appendix G Real64 ZoneTotalExfiltrationHeatLoss = 0.0; // Building total heat emission through zone exfiltration; @@ -2118,14 +2121,6 @@ struct HeatBalanceData : BaseGlobalStruct bool DoLatentSizing = false; // true when latent sizing is performed during zone sizing bool isAnyLatentLoad = false; - Array1D ZoneSNLoadHeatEnergy; - Array1D ZoneSNLoadCoolEnergy; - Array1D ZoneSNLoadHeatRate; - Array1D ZoneSNLoadCoolRate; - Array1D ZoneSNLoadPredictedRate; - Array1D ZoneSNLoadPredictedHSPRate; // Predicted load to heating setpoint (unmultiplied) - Array1D ZoneSNLoadPredictedCSPRate; // Predicted load to cooling setpoint (unmultiplied) - EPVector latentReports; Array1D ZoneListSNLoadHeatEnergy; Array1D ZoneListSNLoadCoolEnergy; Array1D ZoneListSNLoadHeatRate; @@ -2281,6 +2276,7 @@ struct HeatBalanceData : BaseGlobalStruct EPVector HeatReclaimVS_DXCoil; EPVector HeatReclaimSimple_WAHPCoil; EPVector ZnAirRpt; + EPVector spaceAirRpt; EPVector TCGlazings; EPVector ZoneCO2Gen; EPVector ZoneRpt; diff --git a/src/EnergyPlus/DataRoomAirModel.hh b/src/EnergyPlus/DataRoomAirModel.hh index f0365d70dc4..e84a386c68e 100644 --- a/src/EnergyPlus/DataRoomAirModel.hh +++ b/src/EnergyPlus/DataRoomAirModel.hh @@ -704,7 +704,7 @@ namespace DataRoomAirModel { struct RoomAirModelData : BaseGlobalStruct { - + bool anyNonMixingRoomAirModel = false; // True if any zone RoomAirModelType is not Mixing int TotNumOfAirNodes = 0; int TotNumOfRoomAFNNodes = 0; Array1D_int TotNumOfZoneAirNodes; @@ -845,6 +845,7 @@ struct RoomAirModelData : BaseGlobalStruct void clear_state() override { + anyNonMixingRoomAirModel = false; TotNumOfAirNodes = 0; TotNumOfRoomAFNNodes = 0; TotNumOfZoneAirNodes.clear(); diff --git a/src/EnergyPlus/DataStringGlobals.hh b/src/EnergyPlus/DataStringGlobals.hh index 9571681ac40..41fd5fdc9e3 100644 --- a/src/EnergyPlus/DataStringGlobals.hh +++ b/src/EnergyPlus/DataStringGlobals.hh @@ -82,6 +82,8 @@ namespace DataStringGlobals { char constexpr CharSemicolon(';'); // semicolon char constexpr CharTab('\t'); // tab char constexpr CharSpace(' '); // space + constexpr std::string_view zonePrefix = "Zone"; + constexpr std::string_view spacePrefix = "Space"; extern std::string const VerString; // String that represents version information extern std::string const MatchVersion; // String to be matched by Version object diff --git a/src/EnergyPlus/DataSurfaces.cc b/src/EnergyPlus/DataSurfaces.cc index ff0467b05fc..4e27178fd73 100644 --- a/src/EnergyPlus/DataSurfaces.cc +++ b/src/EnergyPlus/DataSurfaces.cc @@ -56,7 +56,6 @@ #include #include #include -#include #include #include #include @@ -64,6 +63,7 @@ #include #include #include +#include namespace EnergyPlus::DataSurfaces { @@ -80,7 +80,6 @@ namespace EnergyPlus::DataSurfaces { using namespace DataVectorTypes; using namespace DataBSDFWindow; using namespace DataHeatBalance; -using namespace DataHeatBalFanSys; using namespace DataZoneEquipment; using namespace DataLoopNode; using namespace Psychrometrics; @@ -227,9 +226,10 @@ Real64 SurfaceData::getInsideAirTemperature(EnergyPlusData &state, const int t_S Real64 RefAirTemp = 0; // determine reference air temperature for this surface + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(this->Zone); switch (state.dataSurface->SurfTAirRef(t_SurfNum)) { case RefAirTemp::ZoneMeanAirTemp: { - RefAirTemp = state.dataHeatBalFanSys->MAT(Zone); + RefAirTemp = thisZoneHB.MAT; } break; case RefAirTemp::AdjacentAirTemp: { RefAirTemp = state.dataHeatBal->SurfTempEffBulkAir(t_SurfNum); @@ -250,7 +250,7 @@ Real64 SurfaceData::getInsideAirTemperature(EnergyPlusData &state, const int t_S for (int NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(Zone).NumInletNodes; ++NodeNum) { Real64 NodeTemp = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(Zone).InletNode(NodeNum)).Temp; Real64 MassFlowRate = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(Zone).InletNode(NodeNum)).MassFlowRate; - Real64 CpAir = PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(Zone)); + Real64 CpAir = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat); SumSysMCp += MassFlowRate * CpAir; SumSysMCpT += MassFlowRate * CpAir * NodeTemp; } @@ -259,12 +259,12 @@ Real64 SurfaceData::getInsideAirTemperature(EnergyPlusData &state, const int t_S // a weighted average of the inlet temperatures. RefAirTemp = SumSysMCpT / SumSysMCp; } else { - RefAirTemp = state.dataHeatBalFanSys->MAT(Zone); + RefAirTemp = thisZoneHB.MAT; } } break; default: { // currently set to mean air temp but should add error warning here - RefAirTemp = state.dataHeatBalFanSys->MAT(Zone); + RefAirTemp = thisZoneHB.MAT; } break; } diff --git a/src/EnergyPlus/DataSurfaces.hh b/src/EnergyPlus/DataSurfaces.hh index 30dd653bf04..c530c708fdf 100644 --- a/src/EnergyPlus/DataSurfaces.hh +++ b/src/EnergyPlus/DataSurfaces.hh @@ -729,10 +729,9 @@ namespace DataSurfaces { Real64 GndReflSolarRad; // ground surface reflected solar radiation on exterior surfaces bool SurfHasSurroundingSurfProperty; // true if surrounding surfaces properties are listed for an external surface bool SurfSchedExternalShadingFrac; // true if the external shading is scheduled or calculated externally to be imported - bool SurfHasLinkedOutAirNode; // true if an OutdoorAir::Node is linked to the surface int SurfSurroundingSurfacesNum; // Index of a surrounding surfaces list (defined in SurfaceProperties::SurroundingSurfaces) int SurfExternalShadingSchInd; // Schedule for a the external shading - int SurfLinkedOutAirNode; // Index of the an OutdoorAir:Node + int SurfLinkedOutAirNode; // Index of the an OutdoorAir:Node, zero if none Real64 AE = 0.0; // Product of area and emissivity for each surface Real64 enclAESum = 0.0; // Sum of area times emissivity for all other surfaces in enclosure @@ -752,7 +751,7 @@ namespace DataSurfaces { SolarEnclIndex(0), SolarEnclSurfIndex(0), IsAirBoundarySurf(false), ConvOrientation(ConvectionConstants::SurfConvOrientation::Invalid), IsSurfPropertyGndSurfacesDefined(false), SurfPropertyGndSurfIndex(0), UseSurfPropertyGndSurfTemp(false), UseSurfPropertyGndSurfRefl(false), GndReflSolarRad(0.0), SurfHasSurroundingSurfProperty(false), SurfSchedExternalShadingFrac(false), - SurfHasLinkedOutAirNode(false), SurfSurroundingSurfacesNum(0), SurfExternalShadingSchInd(0), SurfLinkedOutAirNode(0) + SurfSurroundingSurfacesNum(0), SurfExternalShadingSchInd(0), SurfLinkedOutAirNode(0) { } diff --git a/src/EnergyPlus/DataZoneEnergyDemands.cc b/src/EnergyPlus/DataZoneEnergyDemands.cc new file mode 100644 index 00000000000..1b042a0b609 --- /dev/null +++ b/src/EnergyPlus/DataZoneEnergyDemands.cc @@ -0,0 +1,397 @@ +// EnergyPlus, Copyright (c) 1996-2023, 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. + +// EnergyPlus Headers +#include +#include +#include +#include +#include + +namespace EnergyPlus::DataZoneEnergyDemands { + +void ZoneSystemSensibleDemand::beginEnvironmentInit() +{ + this->RemainingOutputRequired = 0.0; + this->TotalOutputRequired = 0.0; + if (allocated(this->SequencedOutputRequired)) { + for (int equipNum = 1; equipNum <= this->NumZoneEquipment; ++equipNum) { + this->SequencedOutputRequired(equipNum) = 0.0; + this->SequencedOutputRequiredToHeatingSP(equipNum) = 0.0; + this->SequencedOutputRequiredToCoolingSP(equipNum) = 0.0; + } + } + this->ZoneSNLoadHeatEnergy = 0.0; + this->ZoneSNLoadCoolEnergy = 0.0; + this->ZoneSNLoadHeatRate = 0.0; + this->ZoneSNLoadCoolRate = 0.0; + this->ZoneSNLoadPredictedRate = 0.0; + this->ZoneSNLoadPredictedHSPRate = 0.0; + this->ZoneSNLoadPredictedCSPRate = 0.0; +} + +void ZoneSystemMoistureDemand::beginEnvironmentInit() +{ + this->RemainingOutputRequired = 0.0; + this->TotalOutputRequired = 0.0; + if (allocated(this->SequencedOutputRequired)) { + for (int equipNum = 1; equipNum <= this->NumZoneEquipment; ++equipNum) { + this->SequencedOutputRequired(equipNum) = 0.0; + this->SequencedOutputRequiredToHumidSP(equipNum) = 0.0; + this->SequencedOutputRequiredToDehumidSP(equipNum) = 0.0; + } + } + this->ZoneLTLoadHeatEnergy = 0.0; + this->ZoneLTLoadCoolEnergy = 0.0; + this->ZoneLTLoadHeatRate = 0.0; + this->ZoneLTLoadCoolRate = 0.0; + this->ZoneSensibleHeatRatio = 0.0; + this->ZoneVaporPressureDifference = 0.0; + this->ZoneMoisturePredictedRate = 0.0; + this->ZoneMoisturePredictedHumSPRate = 0.0; + this->ZoneMoisturePredictedDehumSPRate = 0.0; +} +void ZoneSystemSensibleDemand::setUpOutputVars(EnergyPlusData &state, + std::string_view prefix, + std::string_view name, + bool const staged, + bool const attachMeters, + int const zoneMult, + int const listMult) +{ + if (attachMeters) { + SetupOutputVariable(state, + format("{} Air System Sensible Heating Energy", prefix), + OutputProcessor::Unit::J, + this->ZoneSNLoadHeatEnergy, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Summed, + name, + _, + "ENERGYTRANSFER", + "Heating", + _, + "Building", + name, + zoneMult, + listMult); + SetupOutputVariable(state, + format("{} Air System Sensible Cooling Energy", prefix), + OutputProcessor::Unit::J, + this->ZoneSNLoadCoolEnergy, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Summed, + name, + _, + "ENERGYTRANSFER", + "Cooling", + _, + "Building", + name, + zoneMult, + listMult); + } else { + SetupOutputVariable(state, + format("{} Air System Sensible Heating Energy", prefix), + OutputProcessor::Unit::J, + this->ZoneSNLoadHeatEnergy, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Summed, + name); + SetupOutputVariable(state, + format("{} Air System Sensible Cooling Energy", prefix), + OutputProcessor::Unit::J, + this->ZoneSNLoadCoolEnergy, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Summed, + name); + } + SetupOutputVariable(state, + format("{} Air System Sensible Heating Rate", prefix), + OutputProcessor::Unit::W, + this->ZoneSNLoadHeatRate, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + SetupOutputVariable(state, + format("{} Air System Sensible Cooling Rate", prefix), + OutputProcessor::Unit::W, + this->ZoneSNLoadCoolRate, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + // The following output variables are for the predicted Heating/Cooling load for the zone which can be compared to actual load. + // There are two sets of data available: one where zone and group multipliers have been applied and another where the multipliers have + // not. First, these report variables are NOT multiplied by zone and group multipliers + SetupOutputVariable(state, + format("{} Predicted Sensible Load to Setpoint Heat Transfer Rate", prefix), + OutputProcessor::Unit::W, + this->ZoneSNLoadPredictedRate, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + SetupOutputVariable(state, + format("{} Predicted Sensible Load to Heating Setpoint Heat Transfer Rate", prefix), + OutputProcessor::Unit::W, + this->ZoneSNLoadPredictedHSPRate, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + SetupOutputVariable(state, + format("{} Predicted Sensible Load to Cooling Setpoint Heat Transfer Rate", prefix), + OutputProcessor::Unit::W, + this->ZoneSNLoadPredictedCSPRate, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + // Second, these report variable ARE multiplied by zone and group multipliers + SetupOutputVariable(state, + format("{} System Predicted Sensible Load to Setpoint Heat Transfer Rate", prefix), + OutputProcessor::Unit::W, + this->TotalOutputRequired, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + SetupOutputVariable(state, + format("{} System Predicted Sensible Load to Heating Setpoint Heat Transfer Rate", prefix), + OutputProcessor::Unit::W, + this->OutputRequiredToHeatingSP, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + SetupOutputVariable(state, + format("{} System Predicted Sensible Load to Cooling Setpoint Heat Transfer Rate", prefix), + OutputProcessor::Unit::W, + this->OutputRequiredToCoolingSP, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + if (staged) { + SetupOutputVariable(state, + format("{} Thermostat Staged Number", prefix), + OutputProcessor::Unit::None, + this->StageNum, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + } +} + +void ZoneSystemMoistureDemand::setUpOutputVars(EnergyPlusData &state, + std::string_view prefix, + std::string_view name, + [[maybe_unused]] bool const staged, + [[maybe_unused]] bool const attachMeters, + [[maybe_unused]] int const zoneMult, + [[maybe_unused]] int const listMult) +{ + if (state.dataHeatBal->DoLatentSizing) { + SetupOutputVariable(state, + format("{} Air System Latent Heating Energy", prefix), + OutputProcessor::Unit::J, + this->ZoneLTLoadHeatEnergy, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Summed, + name); + SetupOutputVariable(state, + format("{} Air System Latent Cooling Energy", prefix), + OutputProcessor::Unit::J, + this->ZoneLTLoadCoolEnergy, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Summed, + name); + SetupOutputVariable(state, + format("{} Air System Latent Heating Rate", prefix), + OutputProcessor::Unit::W, + this->ZoneLTLoadHeatRate, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + SetupOutputVariable(state, + format("{} Air System Latent Cooling Rate", prefix), + OutputProcessor::Unit::W, + this->ZoneLTLoadCoolRate, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + // temporarily hide these behind DoLatentSizing flag + SetupOutputVariable(state, + format("{} Air System Sensible Heat Ratio", prefix), + OutputProcessor::Unit::None, + this->ZoneSensibleHeatRatio, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + SetupOutputVariable(state, + format("{} Air Vapor Pressure Difference", prefix), + OutputProcessor::Unit::Pa, + this->ZoneVaporPressureDifference, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + } + // The following output variables are for the predicted moisture load for the zone with humidity controlled specified. + // There are two sets of data available: one where zone and group multipliers have been applied and another where the multipliers have + // not. First, these report variables are NOT multiplied by zone and group multipliers + SetupOutputVariable(state, + format("{} Predicted Moisture Load Moisture Transfer Rate", prefix), + OutputProcessor::Unit::kgWater_s, + this->ZoneMoisturePredictedRate, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + SetupOutputVariable(state, + format("{} Predicted Moisture Load to Humidifying Setpoint Moisture Transfer Rate", prefix), + OutputProcessor::Unit::kgWater_s, + this->ZoneMoisturePredictedHumSPRate, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + SetupOutputVariable(state, + format("{} Predicted Moisture Load to Dehumidifying Setpoint Moisture Transfer Rate", prefix), + OutputProcessor::Unit::kgWater_s, + this->ZoneMoisturePredictedDehumSPRate, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + // Second, these report variable ARE multiplied by zone and group multipliers + SetupOutputVariable(state, + format("{} System Predicted Moisture Load Moisture Transfer Rate", prefix), + OutputProcessor::Unit::kgWater_s, + this->TotalOutputRequired, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + SetupOutputVariable(state, + format("{} System Predicted Moisture Load to Humidifying Setpoint Moisture Transfer Rate", prefix), + OutputProcessor::Unit::kgWater_s, + this->OutputRequiredToHumidifyingSP, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + SetupOutputVariable(state, + format("{} System Predicted Moisture Load to Dehumidifying Setpoint Moisture Transfer Rate", prefix), + OutputProcessor::Unit::kgWater_s, + this->OutputRequiredToDehumidifyingSP, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); +} + +void ZoneSystemSensibleDemand::reportZoneAirSystemSensibleLoads(EnergyPlusData &state, Real64 const SNLoad) +{ + this->ZoneSNLoadHeatRate = max(SNLoad, 0.0); + this->ZoneSNLoadCoolRate = std::abs(min(SNLoad, 0.0)); + this->ZoneSNLoadHeatEnergy = this->ZoneSNLoadHeatRate * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour; + this->ZoneSNLoadCoolEnergy = this->ZoneSNLoadCoolRate * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour; +} +void ZoneSystemSensibleDemand::reportSensibleLoadsZoneMultiplier( + EnergyPlusData &state, int const zoneNum, Real64 const totalLoad, Real64 const loadToHeatingSetPoint, Real64 const loadToCoolingSetPoint) +{ + Real64 loadCorrFactor = state.dataHeatBalFanSys->LoadCorrectionFactor(zoneNum); + + this->ZoneSNLoadPredictedRate = totalLoad * loadCorrFactor; + this->ZoneSNLoadPredictedHSPRate = loadToHeatingSetPoint * loadCorrFactor; + this->ZoneSNLoadPredictedCSPRate = loadToCoolingSetPoint * loadCorrFactor; + + Real64 ZoneMultFac = state.dataHeatBal->Zone(zoneNum).Multiplier * state.dataHeatBal->Zone(zoneNum).ListMultiplier; + this->TotalOutputRequired = this->ZoneSNLoadPredictedRate * ZoneMultFac; + this->OutputRequiredToHeatingSP = this->ZoneSNLoadPredictedHSPRate * ZoneMultFac; + this->OutputRequiredToCoolingSP = this->ZoneSNLoadPredictedCSPRate * ZoneMultFac; + + // init each sequenced demand to the full output + if (state.dataHeatBal->Zone(zoneNum).IsControlled && this->NumZoneEquipment > 0) { + for (int equipNum = 1; equipNum <= this->NumZoneEquipment; ++equipNum) { + this->SequencedOutputRequired(equipNum) = this->TotalOutputRequired; + this->SequencedOutputRequiredToHeatingSP(equipNum) = this->OutputRequiredToHeatingSP; + this->SequencedOutputRequiredToCoolingSP(equipNum) = this->OutputRequiredToCoolingSP; + } + } +} + +void ZoneSystemMoistureDemand::reportZoneAirSystemMoistureLoads(EnergyPlusData &state, + Real64 const latentGain, + Real64 const sensibleLoad, + Real64 const vaporPressureDiff) +{ + this->ZoneLTLoadHeatRate = std::abs(min(latentGain, 0.0)); + this->ZoneLTLoadCoolRate = max(latentGain, 0.0); + this->ZoneLTLoadHeatEnergy = this->ZoneLTLoadHeatRate * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour; + this->ZoneLTLoadCoolEnergy = this->ZoneLTLoadCoolRate * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour; + if ((sensibleLoad + latentGain) != 0.0) { + this->ZoneSensibleHeatRatio = sensibleLoad / (sensibleLoad + latentGain); + } else if (sensibleLoad != 0.0) { + this->ZoneSensibleHeatRatio = 1.0; + } else { + this->ZoneSensibleHeatRatio = 0.0; + } + this->ZoneVaporPressureDifference = vaporPressureDiff; +} + +void ZoneSystemMoistureDemand::reportMoistLoadsZoneMultiplier( + EnergyPlusData &state, int const zoneNum, Real64 const totalLoad, Real64 const loadToHumidifySetPoint, Real64 const loadToDehumidifySetPoint) +{ + this->ZoneMoisturePredictedRate = totalLoad; + this->ZoneMoisturePredictedHumSPRate = loadToHumidifySetPoint; + this->ZoneMoisturePredictedDehumSPRate = loadToDehumidifySetPoint; + + Real64 zoneMultFac = state.dataHeatBal->Zone(zoneNum).Multiplier * state.dataHeatBal->Zone(zoneNum).ListMultiplier; + + this->TotalOutputRequired = totalLoad * zoneMultFac; + this->OutputRequiredToHumidifyingSP = loadToHumidifySetPoint * zoneMultFac; + this->OutputRequiredToDehumidifyingSP = loadToDehumidifySetPoint * zoneMultFac; + + // init each sequenced demand to the full output + if (state.dataHeatBal->Zone(zoneNum).IsControlled && this->NumZoneEquipment > 0) { + for (int equipNum = 1; equipNum <= this->NumZoneEquipment; ++equipNum) { + this->SequencedOutputRequired(equipNum) = this->TotalOutputRequired; + this->SequencedOutputRequiredToHumidSP(equipNum) = this->OutputRequiredToHumidifyingSP; + this->SequencedOutputRequiredToDehumidSP(equipNum) = this->OutputRequiredToDehumidifyingSP; + } + } +} +} // namespace EnergyPlus::DataZoneEnergyDemands diff --git a/src/EnergyPlus/DataZoneEnergyDemands.hh b/src/EnergyPlus/DataZoneEnergyDemands.hh index caf6356faa5..dc55ff02fea 100644 --- a/src/EnergyPlus/DataZoneEnergyDemands.hh +++ b/src/EnergyPlus/DataZoneEnergyDemands.hh @@ -53,90 +53,126 @@ // EnergyPlus Headers #include +#include #include namespace EnergyPlus { namespace DataZoneEnergyDemands { - struct ZoneSystemDemandData // Sensible cooling/heating loads to be met (watts) + struct ZoneSystemDemandData // Sensible cooling/heating loads to be met (watts) or Humidification/dehumidification loads to be met (kg water per + // second) { - // Members - Real64 RemainingOutputRequired; // The load each equipment sees as what is remaining with load fractions applied - Real64 UnadjRemainingOutputRequired; // The total unadjusted load remaining to be met - Real64 TotalOutputRequired; - Real64 OutputRequiredToHeatingSP; // Load required to meet heating setpoint (>0 is a heating load) - Real64 OutputRequiredToCoolingSP; // Load required to meet cooling setpoint (<0 is a cooling load) - Real64 RemainingOutputReqToHeatSP; // Remaining load required to meet heating setpoint with load fractions applied (>0 is a heating load) - Real64 RemainingOutputReqToCoolSP; // Remaining load required to meet cooling setpoint with load fractions applied (<0 is a cooling load) - Real64 UnadjRemainingOutputReqToHeatSP; // Remaining unadjusted load required to meet heating setpoint (>0 is a heating load) - Real64 UnadjRemainingOutputReqToCoolSP; // Remaining unadjusted load required to meet cooling setpoint (<0 is a cooling load) - int NumZoneEquipment; // count of zone equipment for this zone, from ZoneHVAC:EquipmentList - Array1D SequencedOutputRequired; - Array1D SequencedOutputRequiredToHeatingSP; // load required to meet heating setpoint by sequence - Array1D SequencedOutputRequiredToCoolingSP; // load required to meet cooling setpoint by sequence - Real64 SupplyAirAdjustFactor; // supply air adjustment factor due to the cap of + Real64 RemainingOutputRequired = 0.0; // The load each equipment sees as what is remaining with load fractions applied [W] (multiplied) + Real64 UnadjRemainingOutputRequired = 0.0; // The total unadjusted load remaining to be met [W] (multiplied) + Real64 TotalOutputRequired = 0.0; // The total output required from all equipment [W] (multiplied) + int NumZoneEquipment = 0; // count of zone equipment for this zone, from ZoneHVAC:EquipmentList + Real64 SupplyAirAdjustFactor = 1.0; // supply air adjustment factor due to the cap of // zone maximum outdoor air fraction - int StageNum; // The stage number when staged thermostate is used: + int StageNum = 0; // The stage number when staged thermostate is used: // 0 no load, >0 Heating stage, <0 Cooling stage - // Default Constructor - ZoneSystemDemandData() - : RemainingOutputRequired(0.0), UnadjRemainingOutputRequired(0.0), TotalOutputRequired(0.0), OutputRequiredToHeatingSP(0.0), - OutputRequiredToCoolingSP(0.0), RemainingOutputReqToHeatSP(0.0), RemainingOutputReqToCoolSP(0.0), UnadjRemainingOutputReqToHeatSP(0.0), - UnadjRemainingOutputReqToCoolSP(0.0), NumZoneEquipment(0), SupplyAirAdjustFactor(1.0), StageNum(0) - { - } + virtual void beginEnvironmentInit() = 0; + + virtual void setUpOutputVars( + EnergyPlusData &state, std::string_view prefix, std::string_view name, bool staged, bool attachMeters, int zoneMult, int listMult) = 0; }; - struct ZoneSystemMoistureDemand // Humidification/dehumidification loads to be met (kg water per second) + struct ZoneSystemSensibleDemand : ZoneSystemDemandData // Sensible cooling/heating loads to be met (watts) + { + Real64 OutputRequiredToHeatingSP = 0.0; // Load required to meet heating setpoint (>0 is a heating load) [W] (multiplied) + Real64 OutputRequiredToCoolingSP = 0.0; // Load required to meet cooling setpoint (<0 is a cooling load) [W] (multiplied) + Real64 RemainingOutputReqToHeatSP = + 0.0; // Remaining load required to meet heating setpoint with load fractions applied (>0 is a heating load) [W] (multiplied) + Real64 RemainingOutputReqToCoolSP = + 0.0; // Remaining load required to meet cooling setpoint with load fractions applied (<0 is a cooling load) [W] (multiplied) + Real64 UnadjRemainingOutputReqToHeatSP = + 0.0; // Remaining unadjusted load required to meet heating setpoint (>0 is a heating load) [W] (multiplied) + Real64 UnadjRemainingOutputReqToCoolSP = + 0.0; // Remaining unadjusted load required to meet cooling setpoint (<0 is a cooling load) [W] (multiplied) + EPVector SequencedOutputRequired; // load required to meet setpoint by sequence [W] (multiplied) + EPVector SequencedOutputRequiredToHeatingSP; // load required to meet heating setpoint by sequence [W] (multiplied) + EPVector SequencedOutputRequiredToCoolingSP; // load required to meet cooling setpoint by sequence [W] (multiplied) + Real64 ZoneSNLoadPredictedRate = 0.0; // Predicted sensible load [W] (unmultiplied) + Real64 ZoneSNLoadPredictedHSPRate = 0.0; // Predicted sensible load to heating setpoint [W] (unmultiplied) + Real64 ZoneSNLoadPredictedCSPRate = 0.0; // Predicted sensible load to cooling setpoint [W] (unmultiplied) + Real64 ZoneSNLoadHeatRate = 0.0; // sensible heating rate [W] (unmultiplied) + Real64 ZoneSNLoadCoolRate = 0.0; // sensible cooling rate [W] (unmultiplied) + Real64 ZoneSNLoadHeatEnergy = 0.0; // sensible heating energy [J] (unmultiplied) + Real64 ZoneSNLoadCoolEnergy = 0.0; // sensible cooling energy [J] (unmultiplied) + + void beginEnvironmentInit() override; + + void setUpOutputVars(EnergyPlusData &state, + std::string_view prefix, + std::string_view name, + bool staged, + bool attachMeters, + int zoneMult, + int listMult) override; + + void reportZoneAirSystemSensibleLoads(EnergyPlusData &state, Real64 SNLoad); + + void reportSensibleLoadsZoneMultiplier( + EnergyPlusData &state, int zoneNum, Real64 totalLoad, Real64 loadToHeatingSetPoint, Real64 loadToCoolingSetPoint); + }; + struct ZoneSystemMoistureDemand : ZoneSystemDemandData // Humidification/dehumidification loads to be met (kg water per second) { - // Members - Real64 RemainingOutputRequired; - Real64 UnadjRemainingOutputRequired; // The total unadjusted load remaining to be met - Real64 TotalOutputRequired; - Real64 OutputRequiredToHumidifyingSP; // Load required to meet humidifying setpoint (>0 = a humidify load) - Real64 OutputRequiredToDehumidifyingSP; // Load required to meet dehumidifying setpoint (<0 = a dehumidify load) - Real64 RemainingOutputReqToHumidSP; // Remaining load required to meet humidifying setpoint with load fractions applied - // (>0 is a humidify load) - Real64 RemainingOutputReqToDehumidSP; // Remaining load required to meet dehumidifying setpoint with load fractions applied - // (<0 is a dehumidify load) - Real64 UnadjRemainingOutputReqToHumidSP; // Remaining unadjusted load required to meet humidifying setpoint - // (>0 is a humidify load) - Real64 UnadjRemainingOutputReqToDehumidSP; // Remaining unadjusted load required to meet dehumidifying setpoint - // (<0 is a dehumidify load) - int NumZoneEquipment; // count of zone equipment for this zone, from ZoneHVAC:EquipmentList - Array1D SequencedOutputRequired; - Array1D SequencedOutputRequiredToHumidSP; // load required to meet humidify setpoint by sequence - Array1D SequencedOutputRequiredToDehumidSP; // load required to meet dehumidify setpoint by sequenc - - // Default Constructor - ZoneSystemMoistureDemand() - : RemainingOutputRequired(0.0), UnadjRemainingOutputRequired(0.0), TotalOutputRequired(0.0), OutputRequiredToHumidifyingSP(0.0), - OutputRequiredToDehumidifyingSP(0.0), RemainingOutputReqToHumidSP(0.0), RemainingOutputReqToDehumidSP(0.0), - UnadjRemainingOutputReqToHumidSP(0.0), UnadjRemainingOutputReqToDehumidSP(0.0), NumZoneEquipment(0) - { - } + Real64 OutputRequiredToHumidifyingSP = 0.0; // Load required to meet humidifying setpoint (>0 = a humidify load) [kgWater/s] (multiplied) + Real64 OutputRequiredToDehumidifyingSP = + 0.0; // Load required to meet dehumidifying setpoint (<0 = a dehumidify load) [kgWater/s] (multiplied) + Real64 RemainingOutputReqToHumidSP = 0.0; // Remaining load required to meet humidifying setpoint with load fractions applied + // (>0 is a humidify load) [kgWater/s] (multiplied) + Real64 RemainingOutputReqToDehumidSP = 0.0; // Remaining load required to meet dehumidifying setpoint with load fractions applied + // (<0 is a dehumidify load) [kgWater/s] (multiplied) + Real64 UnadjRemainingOutputReqToHumidSP = 0.0; // Remaining unadjusted load required to meet humidifying setpoint + // (>0 is a humidify load) [kgWater/s] (multiplied) + Real64 UnadjRemainingOutputReqToDehumidSP = 0.0; // Remaining unadjusted load required to meet dehumidifying setpoint + // (<0 is a dehumidify load) [kgWater/s] (multiplied) + EPVector SequencedOutputRequired; // load required to meet setpoint by sequence [kgWater/s] (multiplied) + EPVector SequencedOutputRequiredToHumidSP; // load required to meet humidify setpoint by sequence [kgWater/s] (multiplied) + EPVector SequencedOutputRequiredToDehumidSP; // load required to meet dehumidify setpoint by sequenc [kgWater/s] (multiplied) + Real64 ZoneMoisturePredictedRate = 0.0; // Predicted moisture load to setpoint [kgWater/s] (unmultiplied) + Real64 ZoneMoisturePredictedHumSPRate = 0.0; // Predicted latent load to humidification setpoint [kgWater/s] (unmultiplied) + Real64 ZoneMoisturePredictedDehumSPRate = 0.0; // Predicted latent load to dehumidification setpoint [kgWater/s] (unmultiplied) + Real64 ZoneLTLoadHeatRate = 0.0; // latent heating rate [W] (unmultiplied) + Real64 ZoneLTLoadCoolRate = 0.0; // latent cooling rate [W] (unmultiplied) + Real64 ZoneLTLoadHeatEnergy = 0.0; // latent heating energy [J] (unmultiplied) + Real64 ZoneLTLoadCoolEnergy = 0.0; // latent cooling energy [J] (unmultiplied) + Real64 ZoneSensibleHeatRatio = 0.0; // zone load SHR [] + Real64 ZoneVaporPressureDifference = 0.0; // vapor pressure depression [Pa] + + void beginEnvironmentInit() override; + + void setUpOutputVars(EnergyPlusData &state, + std::string_view prefix, + std::string_view name, + [[maybe_unused]] bool staged = false, + [[maybe_unused]] bool attachMeters = false, + [[maybe_unused]] int zoneMult = 0, + [[maybe_unused]] int listMult = 0) override; + + void reportZoneAirSystemMoistureLoads(EnergyPlusData &state, Real64 latentGain, Real64 sensibleLoad, Real64 vaporPressureDiff); + + void reportMoistLoadsZoneMultiplier( + EnergyPlusData &state, int zoneNum, Real64 totalLoad, Real64 loadToHumidifySetPoint, Real64 loadToDehumidifySetPoint); }; } // namespace DataZoneEnergyDemands struct DataZoneEnergyDemandsData : BaseGlobalStruct { - Array1D_bool DeadBandOrSetback; // true if zone temperature is in the thermostat deadband before any heating / cooling done Array1D_bool Setback; // true if zone temperature has increased from previous setting Array1D_bool CurDeadBandOrSetback; // same as above except updated after each piece of zone equipment in a zone is simulated - Array1D ZoneSysEnergyDemand; - Array1D ZoneSysMoistureDemand; + EPVector ZoneSysEnergyDemand; + EPVector ZoneSysMoistureDemand; + EPVector spaceSysEnergyDemand; + EPVector spaceSysMoistureDemand; void clear_state() override { - this->DeadBandOrSetback.deallocate(); - this->Setback.deallocate(); - this->CurDeadBandOrSetback.deallocate(); - this->ZoneSysEnergyDemand.deallocate(); - this->ZoneSysMoistureDemand.deallocate(); + new (this) DataZoneEnergyDemandsData(); } }; diff --git a/src/EnergyPlus/DataZoneEquipment.cc b/src/EnergyPlus/DataZoneEquipment.cc index 17f34d563c0..56b0233ef47 100644 --- a/src/EnergyPlus/DataZoneEquipment.cc +++ b/src/EnergyPlus/DataZoneEquipment.cc @@ -358,6 +358,10 @@ void GetZoneEquipmentData(EnergyPlusData &state) // assigned to this node if (ControlledZoneNum > 0) { Zone(ControlledZoneNum).SystemZoneNodeNumber = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneNode; + // SpaceHB TODO: For now, assign the same system node to the spaces in the zone + for (int spaceNum : Zone(ControlledZoneNum).spaceIndexes) { + state.dataHeatBal->space(spaceNum).SystemZoneNodeNumber = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneNode; + } } // This error already detected and program will be terminated. ReturnNodeListName = AlphArray(6); diff --git a/src/EnergyPlus/DataZoneEquipment.hh b/src/EnergyPlus/DataZoneEquipment.hh index 97df6500b3a..e558c75d644 100644 --- a/src/EnergyPlus/DataZoneEquipment.hh +++ b/src/EnergyPlus/DataZoneEquipment.hh @@ -518,11 +518,6 @@ struct DataZoneEquipmentData : BaseGlobalStruct bool ZoneEquipSimulatedOnce = false; int NumOfZoneEquipLists = 0; Array1D_int ZoneEquipAvail; - Array1D_bool CrossMixingReportFlag; // TRUE when Cross Mixing is active based on controls - Array1D_bool MixingReportFlag; // TRUE when Mixing is active based on controls - Array1D VentMCP; // Product of mass rate and Cp for each Ventilation object - Array1D ZMAT; // Zone air temperature for zone air mixing - Array1D ZHumRat; // Zone air humidity ratio zone air mixing Array1D ZoneEquipConfig; std::unordered_set UniqueZoneEquipListNames; Array1D ZoneEquipList; @@ -543,11 +538,6 @@ struct DataZoneEquipmentData : BaseGlobalStruct this->ZoneEquipSimulatedOnce = false; this->NumOfZoneEquipLists = 0; this->ZoneEquipAvail.deallocate(); - this->CrossMixingReportFlag.deallocate(); - this->MixingReportFlag.deallocate(); - this->VentMCP.deallocate(); - this->ZMAT.deallocate(); - this->ZHumRat.deallocate(); this->ZoneEquipConfig.deallocate(); this->UniqueZoneEquipListNames.clear(); this->ZoneEquipList.deallocate(); diff --git a/src/EnergyPlus/DaylightingManager.cc b/src/EnergyPlus/DaylightingManager.cc index 1a93a4cf618..f4b6c9d0f9e 100644 --- a/src/EnergyPlus/DaylightingManager.cc +++ b/src/EnergyPlus/DaylightingManager.cc @@ -2019,7 +2019,6 @@ void FigureDayltgCoeffsAtPointsForWindowElements( int IntWinHitNum; // Surface number of interior window that is intersected bool hitIntWin; // Ray from ref pt passes through interior window int PipeNum; // TDD pipe object number - int IntWin; // Interior window surface index Real64 COSBIntWin; // Cos of angle between int win outward normal and ray betw ref pt and // exterior window element or between ref pt and sun @@ -2125,25 +2124,28 @@ void FigureDayltgCoeffsAtPointsForWindowElements( zoneNum = state.dataDaylightingData->IllumMapCalc(MapNum).zoneIndex; } // Does ray pass through an interior window in zone (ZoneNum) containing the ref point? - for (IntWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceFirst; IntWin <= state.dataHeatBal->Zone(zoneNum).WindowSurfaceLast; - ++IntWin) { - if (state.dataSurface->Surface(IntWin).ExtBoundCond >= - 1) { // in develop this was Surface(IntWin).Class == SurfaceClass::Window && Surface(IntWin).ExtBoundCond >= 1 - if (state.dataSurface->Surface(state.dataSurface->Surface(IntWin).ExtBoundCond).Zone == - state.dataSurface->Surface(IWin).Zone) { - PierceSurface(state, IntWin, RREF, Ray, state.dataDaylightingManager->HitPtIntWin, hitIntWin); - if (hitIntWin) { - IntWinHitNum = IntWin; - COSBIntWin = dot(state.dataSurface->Surface(IntWin).OutNormVec, Ray); - if (COSBIntWin <= 0.0) { - hitIntWin = false; - IntWinHitNum = 0; - continue; + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int IntWin = thisSpace.WindowSurfaceFirst; IntWin <= thisSpace.WindowSurfaceLast; ++IntWin) { + if (state.dataSurface->Surface(IntWin).ExtBoundCond >= + 1) { // in develop this was Surface(IntWin).Class == SurfaceClass::Window && Surface(IntWin).ExtBoundCond >= 1 + if (state.dataSurface->Surface(state.dataSurface->Surface(IntWin).ExtBoundCond).Zone == + state.dataSurface->Surface(IWin).Zone) { + PierceSurface(state, IntWin, RREF, Ray, state.dataDaylightingManager->HitPtIntWin, hitIntWin); + if (hitIntWin) { + IntWinHitNum = IntWin; + COSBIntWin = dot(state.dataSurface->Surface(IntWin).OutNormVec, Ray); + if (COSBIntWin <= 0.0) { + hitIntWin = false; + IntWinHitNum = 0; + continue; + } + TVISIntWin = General::POLYF( + COSBIntWin, + state.dataConstruction->Construct(state.dataSurface->Surface(IntWin).Construction).TransVisBeamCoef); + TVISB *= TVISIntWin; + break; // Ray passes thru interior window; exit from DO loop } - TVISIntWin = General::POLYF( - COSBIntWin, state.dataConstruction->Construct(state.dataSurface->Surface(IntWin).Construction).TransVisBeamCoef); - TVISB *= TVISIntWin; - break; // Ray passes thru interior window; exit from DO loop } } } @@ -3418,24 +3420,28 @@ void FigureDayltgCoeffsAtPointsForSunPosition( // Does RAYCOS pass through interior window in zone containing RP? // Loop over zone surfaces looking for interior windows between reference point and sun auto &thisZone = state.dataHeatBal->Zone(zoneNum); - for (int IntWinDisk = thisZone.WindowSurfaceFirst, IntWinDisk_end = thisZone.WindowSurfaceLast; IntWinDisk <= IntWinDisk_end; - ++IntWinDisk) { - if (state.dataSurface->Surface(IntWinDisk).ExtBoundCond >= 1) { - if (state.dataSurface->Surface(state.dataSurface->Surface(IntWinDisk).ExtBoundCond).Zone == - state.dataSurface->Surface(IWin2).Zone) { - PierceSurface(state, IntWinDisk, RREF, RAYCOS, HitPtIntWinDisk, hitIntWinDisk); - if (hitIntWinDisk) { - IntWinDiskHitNum = IntWinDisk; - COSBIntWin = dot(state.dataSurface->Surface(IntWinDisk).OutNormVec, RAYCOS); - if (COSBIntWin <= 0.0) { - hitIntWinDisk = false; - IntWinDiskHitNum = 0; - continue; + for (int spaceNum : thisZone.spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int IntWinDisk = thisSpace.WindowSurfaceFirst, IntWinDisk_end = thisSpace.WindowSurfaceLast; + IntWinDisk <= IntWinDisk_end; + ++IntWinDisk) { + if (state.dataSurface->Surface(IntWinDisk).ExtBoundCond >= 1) { + if (state.dataSurface->Surface(state.dataSurface->Surface(IntWinDisk).ExtBoundCond).Zone == + state.dataSurface->Surface(IWin2).Zone) { + PierceSurface(state, IntWinDisk, RREF, RAYCOS, HitPtIntWinDisk, hitIntWinDisk); + if (hitIntWinDisk) { + IntWinDiskHitNum = IntWinDisk; + COSBIntWin = dot(state.dataSurface->Surface(IntWinDisk).OutNormVec, RAYCOS); + if (COSBIntWin <= 0.0) { + hitIntWinDisk = false; + IntWinDiskHitNum = 0; + continue; + } + TVISIntWinDisk = POLYF( + COSBIntWin, + state.dataConstruction->Construct(state.dataSurface->Surface(IntWinDisk).Construction).TransVisBeamCoef); + break; } - TVISIntWinDisk = POLYF( - COSBIntWin, - state.dataConstruction->Construct(state.dataSurface->Surface(IntWinDisk).Construction).TransVisBeamCoef); - break; } } } @@ -6170,14 +6176,15 @@ void initDaylighting(EnergyPlusData &state, bool const initSurfaceHeatBalancefir DayltgInteriorMapIllum(state); } for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceFirst; - int const lastSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceLast; - for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { - state.dataSurface->SurfWinFracTimeShadingDeviceOn(SurfNum) = 0.0; - if (IS_SHADED(state.dataSurface->SurfWinShadingFlag(SurfNum))) { - state.dataSurface->SurfWinFracTimeShadingDeviceOn(SurfNum) = 1.0; - } else { + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int SurfNum = thisSpace.WindowSurfaceFirst; SurfNum <= thisSpace.WindowSurfaceLast; ++SurfNum) { state.dataSurface->SurfWinFracTimeShadingDeviceOn(SurfNum) = 0.0; + if (IS_SHADED(state.dataSurface->SurfWinShadingFlag(SurfNum))) { + state.dataSurface->SurfWinFracTimeShadingDeviceOn(SurfNum) = 1.0; + } else { + state.dataSurface->SurfWinFracTimeShadingDeviceOn(SurfNum) = 0.0; + } } } } @@ -7219,16 +7226,17 @@ void DayltgInteriorIllum(EnergyPlusData &state, // Loop again over windows and reset remaining shading flags that // are 10 or higher (i.e., conditionally off) to off - for (int IWin = state.dataHeatBal->Zone(thisDaylightControl.zoneIndex).WindowSurfaceFirst; - IWin <= state.dataHeatBal->Zone(thisDaylightControl.zoneIndex).WindowSurfaceLast; - ++IWin) { - if (state.dataSurface->Surface(IWin).ExtBoundCond != ExternalEnvironment) continue; - bool anyGlareControl = BITF_TEST_ANY(BITF(state.dataSurface->SurfWinShadingFlag(IWin)), - BITF(WinShadingType::IntShadeConditionallyOff) | BITF(WinShadingType::GlassConditionallyLightened) | - BITF(WinShadingType::ExtShadeConditionallyOff) | BITF(WinShadingType::IntBlindConditionallyOff) | - BITF(WinShadingType::ExtBlindConditionallyOff)); - if (anyGlareControl) { - state.dataSurface->SurfWinShadingFlag(IWin) = WinShadingType::ShadeOff; + for (int spaceNum : state.dataHeatBal->Zone(thisDaylightControl.zoneIndex).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int IWin = thisSpace.WindowSurfaceFirst; IWin <= thisSpace.WindowSurfaceLast; ++IWin) { + if (state.dataSurface->Surface(IWin).ExtBoundCond != ExternalEnvironment) continue; + bool anyGlareControl = BITF_TEST_ANY(BITF(state.dataSurface->SurfWinShadingFlag(IWin)), + BITF(WinShadingType::IntShadeConditionallyOff) | BITF(WinShadingType::GlassConditionallyLightened) | + BITF(WinShadingType::ExtShadeConditionallyOff) | BITF(WinShadingType::IntBlindConditionallyOff) | + BITF(WinShadingType::ExtBlindConditionallyOff)); + if (anyGlareControl) { + state.dataSurface->SurfWinShadingFlag(IWin) = WinShadingType::ShadeOff; + } } } diff --git a/src/EnergyPlus/DisplacementVentMgr.cc b/src/EnergyPlus/DisplacementVentMgr.cc index 6556a10d2d3..bd326538749 100644 --- a/src/EnergyPlus/DisplacementVentMgr.cc +++ b/src/EnergyPlus/DisplacementVentMgr.cc @@ -72,6 +72,7 @@ #include #include #include +#include namespace EnergyPlus::DisplacementVentMgr { @@ -175,7 +176,6 @@ void HcUCSDDV(EnergyPlusData &state, int const ZoneNum, Real64 const FractionHei // the interface subzone height. // Using/Aliasing - using namespace DataHeatBalFanSys; using namespace DataEnvironment; using namespace DataHeatBalance; using ScheduleManager::GetScheduleIndex; @@ -514,7 +514,6 @@ void CalcUCSDDV(EnergyPlusData &state, int const ZoneNum) // Which Zonenum // "Simplified Models for Heat Transfer in Rooms" G. Carrilho da Graca, Ph.D. thesis UCSD. December 2003. // Using/Aliasing - using namespace DataHeatBalFanSys; using namespace DataEnvironment; using namespace DataHeatBalance; auto &TimeStepSys = state.dataHVACGlobal->TimeStepSys; @@ -558,7 +557,6 @@ void CalcUCSDDV(EnergyPlusData &state, int const ZoneNum) // Which Zonenum Real64 NumberOfPlumes; Real64 SumMCp; Real64 SumMCpT; - Real64 AirCap; Real64 TempHistTerm; Real64 PowerPerPlume; Real64 HeightMixedSubzoneAve; // Height of center of mixed air subzone @@ -575,6 +573,7 @@ void CalcUCSDDV(EnergyPlusData &state, int const ZoneNum) // Which Zonenum auto &TempIndCoef = state.dataDispVentMgr->TempIndCoef; Real64 RetAirGain; + assert(state.dataRoomAirMod->AirModel.allocated()); // Exact solution or Euler method if (state.dataHeatBal->ZoneAirSolutionAlgo != DataHeatBalance::SolutionAlgo::ThirdOrder) { @@ -602,6 +601,7 @@ void CalcUCSDDV(EnergyPlusData &state, int const ZoneNum) // Which Zonenum state.dataRoomAirMod->DVHcIn = state.dataHeatBalSurf->SurfHConvInt; CeilingHeight = state.dataRoomAirMod->ZoneCeilingHeight((ZoneNum - 1) * 2 + 2) - state.dataRoomAirMod->ZoneCeilingHeight((ZoneNum - 1) * 2 + 1); ZoneMult = Zone(ZoneNum).Multiplier * Zone(ZoneNum).ListMultiplier; + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); for (Ctd = 1; Ctd <= state.dataRoomAirMod->TotUCSDDV; ++Ctd) { if (ZoneNum == state.dataRoomAirMod->ZoneUCSDDV(Ctd).ZonePtr) { @@ -615,7 +615,7 @@ void CalcUCSDDV(EnergyPlusData &state, int const ZoneNum) // Which Zonenum ConvGainsOccupiedSubzone = SumInternalConvectionGainsByTypes(state, ZoneNum, DisplacementVentMgr::IntGainTypesOccupied); - ConvGainsOccupiedSubzone += 0.5 * state.dataHeatBalFanSys->SysDepZoneLoadsLagged(ZoneNum); + ConvGainsOccupiedSubzone += 0.5 * thisZoneHB.SysDepZoneLoadsLagged; // Add heat to return air if zonal system (no return air) or cycling system (return air frequently very // low or zero) @@ -625,8 +625,8 @@ void CalcUCSDDV(EnergyPlusData &state, int const ZoneNum) // Which Zonenum } ConvGainsMixedSubzone = SumInternalConvectionGainsByTypes(state, ZoneNum, DisplacementVentMgr::IntGainTypesMixedSubzone); - ConvGainsMixedSubzone += state.dataHeatBalFanSys->SumConvHTRadSys(ZoneNum) + state.dataHeatBalFanSys->SumConvPool(ZoneNum) + - 0.5 * state.dataHeatBalFanSys->SysDepZoneLoadsLagged(ZoneNum); + ConvGainsMixedSubzone += + state.dataHeatBalFanSys->SumConvHTRadSys(ZoneNum) + state.dataHeatBalFanSys->SumConvPool(ZoneNum) + 0.5 * thisZoneHB.SysDepZoneLoadsLagged; if (Zone(ZoneNum).NoHeatToReturnAir) { RetAirGain = SumReturnAirConvectionGainsByTypes(state, ZoneNum, DisplacementVentMgr::IntGainTypesMixedSubzone); ConvGainsMixedSubzone += RetAirGain; @@ -643,17 +643,15 @@ void CalcUCSDDV(EnergyPlusData &state, int const ZoneNum) // Which Zonenum for (NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).NumInletNodes; ++NodeNum) { NodeTemp = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).InletNode(NodeNum)).Temp; MassFlowRate = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).InletNode(NodeNum)).MassFlowRate; - CpAir = PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)); + CpAir = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat); SumSysMCp += MassFlowRate * CpAir; SumSysMCpT += MassFlowRate * CpAir * NodeTemp; } } - SumMCp = state.dataHeatBalFanSys->MCPI(ZoneNum) + state.dataHeatBalFanSys->MCPV(ZoneNum) + state.dataHeatBalFanSys->MCPM(ZoneNum) + - state.dataHeatBalFanSys->MCPE(ZoneNum) + state.dataHeatBalFanSys->MCPC(ZoneNum) + state.dataHeatBalFanSys->MDotCPOA(ZoneNum); - SumMCpT = state.dataHeatBalFanSys->MCPTI(ZoneNum) + state.dataHeatBalFanSys->MCPTV(ZoneNum) + state.dataHeatBalFanSys->MCPTM(ZoneNum) + - state.dataHeatBalFanSys->MCPTE(ZoneNum) + state.dataHeatBalFanSys->MCPTC(ZoneNum) + - state.dataHeatBalFanSys->MDotCPOA(ZoneNum) * Zone(ZoneNum).OutDryBulbTemp; + SumMCp = thisZoneHB.MCPI + thisZoneHB.MCPV + thisZoneHB.MCPM + thisZoneHB.MCPE + thisZoneHB.MCPC + thisZoneHB.MDotCPOA; + SumMCpT = thisZoneHB.MCPTI + thisZoneHB.MCPTV + thisZoneHB.MCPTM + thisZoneHB.MCPTE + thisZoneHB.MCPTC + + thisZoneHB.MDotCPOA * Zone(ZoneNum).OutDryBulbTemp; if (state.afn->simulation_control.type == AirflowNetwork::ControlType::MultizoneWithoutDistribution) { SumMCp = state.afn->exchangeData(ZoneNum).SumMCp + state.afn->exchangeData(ZoneNum).SumMVCp + state.afn->exchangeData(ZoneNum).SumMMCp; SumMCpT = state.afn->exchangeData(ZoneNum).SumMCpT + state.afn->exchangeData(ZoneNum).SumMVCpT + state.afn->exchangeData(ZoneNum).SumMMCpT; @@ -792,21 +790,18 @@ void CalcUCSDDV(EnergyPlusData &state, int const ZoneNum) // Which Zonenum state.dataRoomAirMod->AIRRATFloor(ZoneNum) = Zone(ZoneNum).Volume * min(state.dataRoomAirMod->HeightTransition(ZoneNum), state.dataDispVentMgr->HeightFloorSubzoneTop) / CeilingHeight * Zone(ZoneNum).ZoneVolCapMultpSens * - PsyRhoAirFnPbTdbW( - state, state.dataEnvrn->OutBaroPress, state.dataRoomAirMod->MATFloor(ZoneNum), state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)) * - PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)) / (TimeStepSys * DataGlobalConstants::SecInHour); + PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, state.dataRoomAirMod->MATFloor(ZoneNum), thisZoneHB.ZoneAirHumRat) * + PsyCpAirFnW(thisZoneHB.ZoneAirHumRat) / (TimeStepSys * DataGlobalConstants::SecInHour); state.dataRoomAirMod->AIRRATOC(ZoneNum) = Zone(ZoneNum).Volume * (state.dataRoomAirMod->HeightTransition(ZoneNum) - min(state.dataRoomAirMod->HeightTransition(ZoneNum), 0.2)) / CeilingHeight * Zone(ZoneNum).ZoneVolCapMultpSens * - PsyRhoAirFnPbTdbW( - state, state.dataEnvrn->OutBaroPress, state.dataRoomAirMod->MATOC(ZoneNum), state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)) * - PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)) / (TimeStepSys * DataGlobalConstants::SecInHour); + PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, state.dataRoomAirMod->MATOC(ZoneNum), thisZoneHB.ZoneAirHumRat) * + PsyCpAirFnW(thisZoneHB.ZoneAirHumRat) / (TimeStepSys * DataGlobalConstants::SecInHour); state.dataRoomAirMod->AIRRATMX(ZoneNum) = Zone(ZoneNum).Volume * (CeilingHeight - state.dataRoomAirMod->HeightTransition(ZoneNum)) / CeilingHeight * Zone(ZoneNum).ZoneVolCapMultpSens * - PsyRhoAirFnPbTdbW( - state, state.dataEnvrn->OutBaroPress, state.dataRoomAirMod->MATMX(ZoneNum), state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)) * - PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)) / (TimeStepSys * DataGlobalConstants::SecInHour); + PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, state.dataRoomAirMod->MATMX(ZoneNum), thisZoneHB.ZoneAirHumRat) * + PsyCpAirFnW(thisZoneHB.ZoneAirHumRat) / (TimeStepSys * DataGlobalConstants::SecInHour); if (UseZoneTimeStepHistory) { state.dataRoomAirMod->ZTM3Floor(ZoneNum) = state.dataRoomAirMod->XM3TFloor(ZoneNum); @@ -835,11 +830,11 @@ void CalcUCSDDV(EnergyPlusData &state, int const ZoneNum) // Which Zonenum state.dataRoomAirMod->ZTM1MX(ZoneNum) = state.dataRoomAirMod->DSXMATMX(ZoneNum); } - AirCap = state.dataRoomAirMod->AIRRATFloor(ZoneNum); + Real64 AirCap = state.dataRoomAirMod->AIRRATFloor(ZoneNum); TempHistTerm = AirCap * (3.0 * state.dataRoomAirMod->ZTM1Floor(ZoneNum) - (3.0 / 2.0) * state.dataRoomAirMod->ZTM2Floor(ZoneNum) + OneThird * state.dataRoomAirMod->ZTM3Floor(ZoneNum)); TempDepCoef = state.dataDispVentMgr->HA_FLOOR + MCp_Total; - TempIndCoef = state.dataDispVentMgr->HAT_FLOOR + MCpT_Total + state.dataHeatBalFanSys->NonAirSystemResponse(ZoneNum) / ZoneMult; + TempIndCoef = state.dataDispVentMgr->HAT_FLOOR + MCpT_Total + thisZoneHB.NonAirSystemResponse / ZoneMult; switch (state.dataHeatBal->ZoneAirSolutionAlgo) { case DataHeatBalance::SolutionAlgo::ThirdOrder: { state.dataRoomAirMod->ZTFloor(ZoneNum) = calculateThirdOrderFloorTemperature(TempHistTerm, @@ -848,7 +843,7 @@ void CalcUCSDDV(EnergyPlusData &state, int const ZoneNum) // Which Zonenum MCpT_Total, MCp_Total, state.dataRoomAirMod->ZTOC(ZoneNum), - state.dataHeatBalFanSys->NonAirSystemResponse(ZoneNum), + thisZoneHB.NonAirSystemResponse, ZoneMult, AirCap); } break; @@ -949,9 +944,9 @@ void CalcUCSDDV(EnergyPlusData &state, int const ZoneNum) // Which Zonenum state.dataRoomAirMod->AvgTempGrad(ZoneNum) = 0.0; state.dataRoomAirMod->MaxTempGrad(ZoneNum) = 0.0; state.dataRoomAirMod->AirModel(ZoneNum).SimAirModel = false; - AirCap = state.dataHeatBalFanSys->AIRRAT(ZoneNum); - TempHistTerm = AirCap * (3.0 * state.dataHeatBalFanSys->ZTM1(ZoneNum) - (3.0 / 2.0) * state.dataHeatBalFanSys->ZTM2(ZoneNum) + - OneThird * state.dataHeatBalFanSys->ZTM3(ZoneNum)); + Real64 const thisZoneT1 = thisZoneHB.ZoneT1; + Real64 AirCap = thisZoneHB.AirPowerCap; + TempHistTerm = AirCap * (3.0 * thisZoneHB.ZTM[0] - (3.0 / 2.0) * thisZoneHB.ZTM[1] + OneThird * thisZoneHB.ZTM[2]); for (Ctd = 1; Ctd <= 3; ++Ctd) { TempDepCoef = state.dataDispVentMgr->HA_MX + state.dataDispVentMgr->HA_OC + state.dataDispVentMgr->HA_FLOOR + MCp_Total; @@ -965,15 +960,13 @@ void CalcUCSDDV(EnergyPlusData &state, int const ZoneNum) // Which Zonenum } break; case DataHeatBalance::SolutionAlgo::AnalyticalSolution: { if (TempDepCoef == 0.0) { // B=0 - ZTAveraged = state.dataHeatBalFanSys->ZoneT1(ZoneNum) + TempIndCoef / AirCap; + ZTAveraged = thisZoneT1 + TempIndCoef / AirCap; } else { - ZTAveraged = - (state.dataHeatBalFanSys->ZoneT1(ZoneNum) - TempIndCoef / TempDepCoef) * std::exp(min(700.0, -TempDepCoef / AirCap)) + - TempIndCoef / TempDepCoef; + ZTAveraged = (thisZoneT1 - TempIndCoef / TempDepCoef) * std::exp(min(700.0, -TempDepCoef / AirCap)) + TempIndCoef / TempDepCoef; } } break; case DataHeatBalance::SolutionAlgo::EulerMethod: { - ZTAveraged = (AirCap * state.dataHeatBalFanSys->ZoneT1(ZoneNum) + TempIndCoef) / (AirCap + TempDepCoef); + ZTAveraged = (AirCap * thisZoneT1 + TempIndCoef) / (AirCap + TempDepCoef); } break; default: break; @@ -993,15 +986,13 @@ void CalcUCSDDV(EnergyPlusData &state, int const ZoneNum) // Which Zonenum } break; case DataHeatBalance::SolutionAlgo::AnalyticalSolution: { if (TempDepCoef == 0.0) { // B=0 - ZTAveraged = state.dataHeatBalFanSys->ZoneT1(ZoneNum) + TempIndCoef / AirCap; + ZTAveraged = thisZoneT1 + TempIndCoef / AirCap; } else { - ZTAveraged = - (state.dataHeatBalFanSys->ZoneT1(ZoneNum) - TempIndCoef / TempDepCoef) * std::exp(min(700.0, -TempDepCoef / AirCap)) + - TempIndCoef / TempDepCoef; + ZTAveraged = (thisZoneT1 - TempIndCoef / TempDepCoef) * std::exp(min(700.0, -TempDepCoef / AirCap)) + TempIndCoef / TempDepCoef; } } break; case DataHeatBalance::SolutionAlgo::EulerMethod: { - ZTAveraged = (AirCap * state.dataHeatBalFanSys->ZoneT1(ZoneNum) + TempIndCoef) / (AirCap + TempDepCoef); + ZTAveraged = (AirCap * thisZoneT1 + TempIndCoef) / (AirCap + TempDepCoef); } break; default: break; diff --git a/src/EnergyPlus/EarthTube.cc b/src/EnergyPlus/EarthTube.cc index 7bed6704dc7..fd4eaccd924 100644 --- a/src/EnergyPlus/EarthTube.cc +++ b/src/EnergyPlus/EarthTube.cc @@ -56,7 +56,6 @@ #include #include #include -#include #include #include #include @@ -65,6 +64,7 @@ #include #include #include +#include namespace EnergyPlus::EarthTube { // Module containing the data for Earth Tube system @@ -542,7 +542,6 @@ void CalcEarthTube(EnergyPlusData &state) // SUBROUTINE LOCAL VARIABLE DECLARATIONS: int Loop; - int NZ; Real64 Process1; // Variable Used in the Middle of the Calculation Real64 GroundTempz1z2t; // Average Ground Temperature between Depth z1 and z2 at time t @@ -563,38 +562,41 @@ void CalcEarthTube(EnergyPlusData &state) Real64 AirMassFlowRate; // Actual Mass Flow Rate of Air inside Pipe Real64 AirSpecHeat; // Specific Heat of Air Real64 AirDensity; // Density of Air - Real64 EVF; - state.dataHeatBalFanSys->MCPTE = 0.0; - state.dataHeatBalFanSys->MCPE = 0.0; - state.dataHeatBalFanSys->EAMFL = 0.0; - state.dataHeatBalFanSys->EAMFLxHumRat = 0.0; int numEarthTubes = (int)state.dataEarthTube->EarthTubeSys.size(); for (Loop = 1; Loop <= numEarthTubes; ++Loop) { auto &thisEarthTube = state.dataEarthTube->EarthTubeSys(Loop); - NZ = thisEarthTube.ZonePtr; + int NZ = thisEarthTube.ZonePtr; + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ); + thisZoneHB.MCPTE = 0.0; + thisZoneHB.MCPE = 0.0; + thisZoneHB.EAMFL = 0.0; + thisZoneHB.EAMFLxHumRat = 0.0; thisEarthTube.FanPower = 0.0; + // Skip this if the zone is below the minimum temperature limit - if (state.dataHeatBalFanSys->MAT(NZ) < thisEarthTube.MinTemperature) continue; + if (state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ).MAT < thisEarthTube.MinTemperature) continue; // Skip this if the zone is above the maximum temperature limit - if (state.dataHeatBalFanSys->MAT(NZ) > thisEarthTube.MaxTemperature) continue; + if (state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ).MAT > thisEarthTube.MaxTemperature) continue; // Skip if below the temperature difference limit - if (std::abs(state.dataHeatBalFanSys->MAT(NZ) - state.dataEnvrn->OutDryBulbTemp) < thisEarthTube.DelTemperature) continue; + if (std::abs(state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ).MAT - state.dataEnvrn->OutDryBulbTemp) < thisEarthTube.DelTemperature) + continue; AirDensity = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, state.dataEnvrn->OutDryBulbTemp, state.dataEnvrn->OutHumRat); AirSpecHeat = Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat); EVF = thisEarthTube.DesignLevel * ScheduleManager::GetCurrentScheduleValue(state, thisEarthTube.SchedPtr); - state.dataHeatBalFanSys->MCPE(NZ) = + thisZoneHB.MCPE = EVF * AirDensity * AirSpecHeat * (thisEarthTube.ConstantTermCoef + - std::abs(state.dataEnvrn->OutDryBulbTemp - state.dataHeatBalFanSys->MAT(NZ)) * thisEarthTube.TemperatureTermCoef + + std::abs(state.dataEnvrn->OutDryBulbTemp - state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ).MAT) * + thisEarthTube.TemperatureTermCoef + state.dataEnvrn->WindSpeed * (thisEarthTube.VelocityTermCoef + state.dataEnvrn->WindSpeed * thisEarthTube.VelocitySQTermCoef)); - state.dataHeatBalFanSys->EAMFL(NZ) = state.dataHeatBalFanSys->MCPE(NZ) / AirSpecHeat; + thisZoneHB.EAMFL = thisZoneHB.MCPE / AirSpecHeat; if (thisEarthTube.FanEfficiency > 0.0) { - thisEarthTube.FanPower = state.dataHeatBalFanSys->EAMFL(NZ) * thisEarthTube.FanPressure / (thisEarthTube.FanEfficiency * AirDensity); + thisEarthTube.FanPower = thisZoneHB.EAMFL * thisEarthTube.FanPressure / (thisEarthTube.FanEfficiency * AirDensity); } AverPipeAirVel = EVF / DataGlobalConstants::Pi / pow_2(thisEarthTube.r1); @@ -673,7 +675,8 @@ void EarthTubeData::CalcEarthTubeHumRat(EnergyPlusData &state, int const NZ) // and calculates parameters associated with humidity ratio. Real64 InsideDewPointTemp = Psychrometrics::PsyTdpFnWPb(state, state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress); - Real64 InsideHumRat; + Real64 InsideHumRat = 0.0; + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ); if (this->InsideAirTemp >= InsideDewPointTemp) { InsideHumRat = state.dataEnvrn->OutHumRat; @@ -681,16 +684,16 @@ void EarthTubeData::CalcEarthTubeHumRat(EnergyPlusData &state, int const NZ) // Intake fans will add some heat to the air, raising the temperature for an intake fan... if (this->FanType == Ventilation::Intake) { Real64 OutletAirEnthalpy; - if (state.dataHeatBalFanSys->EAMFL(NZ) == 0.0) { + if (thisZoneHB.EAMFL == 0.0) { OutletAirEnthalpy = InsideEnthalpy; } else { - OutletAirEnthalpy = InsideEnthalpy + this->FanPower / state.dataHeatBalFanSys->EAMFL(NZ); + OutletAirEnthalpy = InsideEnthalpy + this->FanPower / thisZoneHB.EAMFL; } this->AirTemp = Psychrometrics::PsyTdbFnHW(OutletAirEnthalpy, state.dataEnvrn->OutHumRat); } else { this->AirTemp = this->InsideAirTemp; } - state.dataHeatBalFanSys->MCPTE(NZ) = state.dataHeatBalFanSys->MCPE(NZ) * this->AirTemp; + thisZoneHB.MCPTE = thisZoneHB.MCPE * this->AirTemp; } else { InsideHumRat = Psychrometrics::PsyWFnTdpPb(state, this->InsideAirTemp, state.dataEnvrn->OutBaroPress); @@ -698,21 +701,21 @@ void EarthTubeData::CalcEarthTubeHumRat(EnergyPlusData &state, int const NZ) // Intake fans will add some heat to the air, raising the temperature for an intake fan... if (this->FanType == Ventilation::Intake) { Real64 OutletAirEnthalpy; - if (state.dataHeatBalFanSys->EAMFL(NZ) == 0.0) { + if (thisZoneHB.EAMFL == 0.0) { OutletAirEnthalpy = InsideEnthalpy; } else { - OutletAirEnthalpy = InsideEnthalpy + this->FanPower / state.dataHeatBalFanSys->EAMFL(NZ); + OutletAirEnthalpy = InsideEnthalpy + this->FanPower / thisZoneHB.EAMFL; } this->AirTemp = Psychrometrics::PsyTdbFnHW(OutletAirEnthalpy, InsideHumRat); } else { this->AirTemp = this->InsideAirTemp; } - state.dataHeatBalFanSys->MCPTE(NZ) = state.dataHeatBalFanSys->MCPE(NZ) * this->AirTemp; + thisZoneHB.MCPTE = thisZoneHB.MCPE * this->AirTemp; } this->HumRat = InsideHumRat; this->WetBulbTemp = Psychrometrics::PsyTwbFnTdbWPb(state, this->InsideAirTemp, InsideHumRat, state.dataEnvrn->OutBaroPress); - state.dataHeatBalFanSys->EAMFLxHumRat(NZ) = state.dataHeatBalFanSys->EAMFL(NZ) * InsideHumRat; + thisZoneHB.EAMFLxHumRat = thisZoneHB.EAMFL * InsideHumRat; } void ReportEarthTube(EnergyPlusData &state) @@ -729,19 +732,18 @@ void ReportEarthTube(EnergyPlusData &state) for (int ZoneLoop = 1; ZoneLoop <= state.dataGlobal->NumOfZones; ++ZoneLoop) { // Start of zone loads report variable update loop ... auto &thisZone = state.dataEarthTube->ZnRptET(ZoneLoop); - auto &zoneMCPE = state.dataHeatBalFanSys->MCPE(ZoneLoop); - auto &zoneTemp = state.dataHeatBalFanSys->ZT(ZoneLoop); + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneLoop); // Break the infiltration load into heat gain and loss components. Real64 const AirDensity = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, state.dataEnvrn->OutDryBulbTemp, state.dataEnvrn->OutHumRat); Real64 const CpAir = Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat); - thisZone.EarthTubeVolume = (zoneMCPE / CpAir / AirDensity) * ReportingConstant; - thisZone.EarthTubeMass = (zoneMCPE / CpAir) * ReportingConstant; - thisZone.EarthTubeVolFlowRate = zoneMCPE / CpAir / AirDensity; - thisZone.EarthTubeVolFlowRateStd = zoneMCPE / CpAir / state.dataEnvrn->StdRhoAir; - thisZone.EarthTubeMassFlowRate = zoneMCPE / CpAir; - thisZone.EarthTubeWaterMassFlowRate = state.dataHeatBalFanSys->EAMFLxHumRat(ZoneLoop); + thisZone.EarthTubeVolume = (thisZoneHB.MCPE / CpAir / AirDensity) * ReportingConstant; + thisZone.EarthTubeMass = (thisZoneHB.MCPE / CpAir) * ReportingConstant; + thisZone.EarthTubeVolFlowRate = thisZoneHB.MCPE / CpAir / AirDensity; + thisZone.EarthTubeVolFlowRateStd = thisZoneHB.MCPE / CpAir / state.dataEnvrn->StdRhoAir; + thisZone.EarthTubeMassFlowRate = thisZoneHB.MCPE / CpAir; + thisZone.EarthTubeWaterMassFlowRate = thisZoneHB.EAMFLxHumRat; thisZone.EarthTubeFanElec = 0.0; thisZone.EarthTubeAirTemp = 0.0; @@ -751,14 +753,14 @@ void ReportEarthTube(EnergyPlusData &state) thisZone.EarthTubeFanElecPower = thisEarthTube.FanPower; // Break the EarthTube load into heat gain and loss components. - if (zoneTemp > thisEarthTube.AirTemp) { - thisZone.EarthTubeHeatLoss = zoneMCPE * (zoneTemp - thisEarthTube.AirTemp) * ReportingConstant; - thisZone.EarthTubeHeatLossRate = zoneMCPE * (zoneTemp - thisEarthTube.AirTemp); + if (thisZoneHB.ZT > thisEarthTube.AirTemp) { + thisZone.EarthTubeHeatLoss = thisZoneHB.MCPE * (thisZoneHB.ZT - thisEarthTube.AirTemp) * ReportingConstant; + thisZone.EarthTubeHeatLossRate = thisZoneHB.MCPE * (thisZoneHB.ZT - thisEarthTube.AirTemp); thisZone.EarthTubeHeatGain = 0.0; thisZone.EarthTubeHeatGainRate = 0.0; - } else if (zoneTemp <= thisEarthTube.AirTemp) { - thisZone.EarthTubeHeatGain = zoneMCPE * (thisEarthTube.AirTemp - zoneTemp) * ReportingConstant; - thisZone.EarthTubeHeatGainRate = zoneMCPE * (thisEarthTube.AirTemp - zoneTemp); + } else if (thisZoneHB.ZT <= thisEarthTube.AirTemp) { + thisZone.EarthTubeHeatGain = thisZoneHB.MCPE * (thisEarthTube.AirTemp - thisZoneHB.ZT) * ReportingConstant; + thisZone.EarthTubeHeatGainRate = thisZoneHB.MCPE * (thisEarthTube.AirTemp - thisZoneHB.ZT); thisZone.EarthTubeHeatLoss = 0.0; thisZone.EarthTubeHeatLossRate = 0.0; } @@ -766,7 +768,7 @@ void ReportEarthTube(EnergyPlusData &state) thisZone.EarthTubeAirTemp = thisEarthTube.AirTemp; thisZone.EarthTubeWetBulbTemp = thisEarthTube.WetBulbTemp; thisZone.EarthTubeHumRat = thisEarthTube.HumRat; - thisZone.EarthTubeOATreatmentPower = zoneMCPE * (thisEarthTube.AirTemp - state.dataEnvrn->OutDryBulbTemp); + thisZone.EarthTubeOATreatmentPower = thisZoneHB.MCPE * (thisEarthTube.AirTemp - state.dataEnvrn->OutDryBulbTemp); break; // DO loop } } diff --git a/src/EnergyPlus/EcoRoofManager.cc b/src/EnergyPlus/EcoRoofManager.cc index 4c2985cea95..46697dab3c2 100644 --- a/src/EnergyPlus/EcoRoofManager.cc +++ b/src/EnergyPlus/EcoRoofManager.cc @@ -57,7 +57,6 @@ #include #include #include -#include #include #include #include @@ -68,6 +67,7 @@ #include #include #include +#include namespace EnergyPlus { @@ -129,7 +129,6 @@ namespace EcoRoofManager { // The Atmospheric Boundary Layer - by J.R. Garratt (Cambridge Atmos. & Space Science Series), 316pp. // Using/Aliasing using namespace DataEnvironment; - using namespace DataHeatBalFanSys; using namespace DataHeatBalance; using namespace DataHeatBalSurface; using namespace DataSurfaces; @@ -274,12 +273,13 @@ namespace EcoRoofManager { state.dataEcoRoofMgr->QuickConductionSurf = true; F1temp = state.dataConstruction->Construct(ConstrNum).CTFCross(0) / (state.dataConstruction->Construct(ConstrNum).CTFInside(0) + state.dataHeatBalSurf->SurfHConvInt(SurfNum)); - Qsoilpart1 = -state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + - F1temp * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) + - state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) + - state.dataConstruction->Construct(ConstrNum).CTFSourceIn(0) * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) + - state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataHeatBalFanSys->MAT(ZoneNum) + - state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum)); + Qsoilpart1 = + -state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + + F1temp * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) + + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) + + state.dataConstruction->Construct(ConstrNum).CTFSourceIn(0) * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) + + state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT + + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum)); } else { Qsoilpart1 = -state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) + state.dataConstruction->Construct(ConstrNum).CTFCross(0) * state.dataHeatBalSurf->SurfTempIn(SurfNum); diff --git a/src/EnergyPlus/ElectricBaseboardRadiator.cc b/src/EnergyPlus/ElectricBaseboardRadiator.cc index 3dc5a61ca41..7b6136ec3ba 100644 --- a/src/EnergyPlus/ElectricBaseboardRadiator.cc +++ b/src/EnergyPlus/ElectricBaseboardRadiator.cc @@ -613,7 +613,7 @@ namespace ElectricBaseboardRadiator { } if (state.dataGlobal->BeginTimeStepFlag && FirstHVACIteration) { - ZeroSourceSumHATsurf(ControlledZoneNum) = SumHATsurf(state, ControlledZoneNum); + ZeroSourceSumHATsurf(ControlledZoneNum) = state.dataHeatBal->Zone(ControlledZoneNum).sumHATsurf(state); QBBElecRadSrcAvg(BaseboardNum) = 0.0; LastQBBElecRadSrc(BaseboardNum) = 0.0; LastSysTimeElapsed(BaseboardNum) = 0.0; @@ -818,7 +818,7 @@ namespace ElectricBaseboardRadiator { // that all energy radiated to people is converted to convective energy is // not very precise, but at least it conserves energy. The system impact to heat balance // should include this. - LoadMet = (SumHATsurf(state, ZoneNum) - state.dataElectBaseboardRad->ZeroSourceSumHATsurf(ZoneNum)) + + LoadMet = (state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state) - state.dataElectBaseboardRad->ZeroSourceSumHATsurf(ZoneNum)) + (QBBCap * ElecBaseboard(BaseboardNum).FracConvect) + (RadHeat * ElecBaseboard(BaseboardNum).FracDistribPerson); if (LoadMet < 0.0) { @@ -835,15 +835,15 @@ namespace ElectricBaseboardRadiator { DistributeBBElecRadGains(state); HeatBalanceSurfaceManager::CalcHeatBalanceOutsideSurf(state, ZoneNum); HeatBalanceSurfaceManager::CalcHeatBalanceInsideSurf(state, ZoneNum); - TempZeroSourceSumHATsurf = SumHATsurf(state, ZoneNum); + TempZeroSourceSumHATsurf = state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state); // Now, turn it back on: state.dataElectBaseboardRad->QBBElecRadSource(BaseboardNum) = RadHeat; DistributeBBElecRadGains(state); HeatBalanceSurfaceManager::CalcHeatBalanceOutsideSurf(state, ZoneNum); HeatBalanceSurfaceManager::CalcHeatBalanceInsideSurf(state, ZoneNum); // Recalculate LoadMet with new ZeroSource... term and see if it is positive now. If not, shut it down. - LoadMet = (SumHATsurf(state, ZoneNum) - TempZeroSourceSumHATsurf) + (QBBCap * ElecBaseboard(BaseboardNum).FracConvect) + - (RadHeat * ElecBaseboard(BaseboardNum).FracDistribPerson); + LoadMet = (state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state) - TempZeroSourceSumHATsurf) + + (QBBCap * ElecBaseboard(BaseboardNum).FracConvect) + (RadHeat * ElecBaseboard(BaseboardNum).FracDistribPerson); if (LoadMet < 0.0) { // LoadMet is still less than zero so shut everything down UpdateElectricBaseboardOff(LoadMet, @@ -1098,60 +1098,6 @@ namespace ElectricBaseboardRadiator { ElecBaseboard(BaseboardNum).RadEnergy = ElecBaseboard(BaseboardNum).RadPower * TimeStepSys * DataGlobalConstants::SecInHour; } - Real64 SumHATsurf(EnergyPlusData &state, int const ZoneNum) // Zone number - { - - // FUNCTION INFORMATION: - // AUTHOR Peter Graham Ellis - // DATE WRITTEN July 2003 - - // PURPOSE OF THIS FUNCTION: - // This function calculates the zone sum of Hc*Area*Tsurf. It replaces the old SUMHAT. - // The SumHATsurf code below is also in the CalcZoneSums subroutine in ZoneTempPredictorCorrector - // and should be updated accordingly. - - // Using/Aliasing - using namespace DataSurfaces; - using namespace DataHeatBalance; - - // Return value - Real64 SumHATsurf; - - // FUNCTION LOCAL VARIABLE DECLARATIONS: - int SurfNum; // Surface number - Real64 Area; // Effective surface area - - SumHATsurf = 0.0; - - for (SurfNum = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst; SurfNum <= state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast; ++SurfNum) { - Area = state.dataSurface->Surface(SurfNum).Area; - - if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Window) { - if (ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum))) { - // The area is the shade or blind area = the sum of the glazing area and the divider area (which is zero if no divider) - Area += state.dataSurface->SurfWinDividerArea(SurfNum); - } - - if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) { - // Window frame contribution - SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinFrameArea(SurfNum) * - (1.0 + state.dataSurface->SurfWinProjCorrFrIn(SurfNum)) * state.dataSurface->SurfWinFrameTempIn(SurfNum); - } - - if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0 && - !ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum))) { - // Window divider contribution (only from shade or blind for window with divider and interior shade or blind) - SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinDividerArea(SurfNum) * - (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) * state.dataSurface->SurfWinDividerTempIn(SurfNum); - } - } - - SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * Area * state.dataHeatBalSurf->SurfTempInTmp(SurfNum); - } - - return SumHATsurf; - } - } // namespace ElectricBaseboardRadiator } // namespace EnergyPlus diff --git a/src/EnergyPlus/ElectricBaseboardRadiator.hh b/src/EnergyPlus/ElectricBaseboardRadiator.hh index fb2be9331a9..41f2db562ae 100644 --- a/src/EnergyPlus/ElectricBaseboardRadiator.hh +++ b/src/EnergyPlus/ElectricBaseboardRadiator.hh @@ -147,8 +147,6 @@ namespace ElectricBaseboardRadiator { void ReportElectricBaseboard(EnergyPlusData &state, int const BaseboardNum); - Real64 SumHATsurf(EnergyPlusData &state, int const ZoneNum); // Zone number - } // namespace ElectricBaseboardRadiator struct ElectricBaseboardRadiatorData : BaseGlobalStruct diff --git a/src/EnergyPlus/ElectricPowerServiceManager.cc b/src/EnergyPlus/ElectricPowerServiceManager.cc index e6b0191e762..3745269d5de 100644 --- a/src/EnergyPlus/ElectricPowerServiceManager.cc +++ b/src/EnergyPlus/ElectricPowerServiceManager.cc @@ -59,7 +59,6 @@ #include #include #include -#include #include #include #include @@ -81,6 +80,7 @@ #include #include #include +#include namespace EnergyPlus { @@ -4293,7 +4293,7 @@ void ElectricStorage::simulateLiIonNmcBatteryModel(EnergyPlusData &state, // Set the temperature the battery sees if (zoneNum_ > 0) { // If in a zone, use the zone temperature - battState.thermal->T_room = state.dataHeatBalFanSys->ZT(zoneNum_); + battState.thermal->T_room = state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum_).ZT; } else { // If outside, use outdoor temperature battState.thermal->T_room = state.dataEnvrn->OutDryBulbTemp; diff --git a/src/EnergyPlus/ExhaustAirSystemManager.cc b/src/EnergyPlus/ExhaustAirSystemManager.cc index 3c616db8340..c74e750421f 100644 --- a/src/EnergyPlus/ExhaustAirSystemManager.cc +++ b/src/EnergyPlus/ExhaustAirSystemManager.cc @@ -57,7 +57,6 @@ #include #include #include -#include #include #include #include @@ -73,6 +72,7 @@ #include #include #include +#include namespace EnergyPlus { @@ -334,7 +334,7 @@ namespace ExhaustAirSystemManager { } if (ErrorsFound) { - ShowFatalError(state, "Errors found getting AirLoopHVAC:ExhaustSystem. Preceding condition(s) causes termination."); + ShowFatalError(state, "Errors found getting AirLoopHVAC:ExhaustSystem. Preceding condition(s) causes termination."); } } @@ -708,7 +708,7 @@ namespace ExhaustAirSystemManager { auto &thisExhInlet = state.dataLoopNodes->Node(InletNode); auto &thisExhOutlet = state.dataLoopNodes->Node(OutletNode); Real64 MassFlow = thisExhInlet.MassFlowRate; - Real64 Tin = state.dataHeatBalFanSys->ZT(thisExhCtrl.ZoneNum); + Real64 Tin = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisExhCtrl.ZoneNum).ZT; Real64 thisExhCtrlAvailScheVal = ScheduleManager::GetCurrentScheduleValue(state, thisExhCtrl.AvailScheduleNum); if (present(FlowRatio)) { diff --git a/src/EnergyPlus/FanCoilUnits.cc b/src/EnergyPlus/FanCoilUnits.cc index 5b55f3472de..3f4464fa4fc 100644 --- a/src/EnergyPlus/FanCoilUnits.cc +++ b/src/EnergyPlus/FanCoilUnits.cc @@ -2526,7 +2526,7 @@ namespace FanCoilUnits { Calc4PipeFanCoil(state, FanCoilNum, ControlledZoneNum, FirstHVACIteration, QUnitOut); } } - CalcZoneSensibleOutput(AirMassFlow, Node(OutletNode).Temp, Node(InletNode).Temp, Node(InletNode).HumRat, QUnitOut); + QUnitOut = calcZoneSensibleOutput(AirMassFlow, Node(OutletNode).Temp, Node(InletNode).Temp, Node(InletNode).HumRat); // if heating } else if (UnitOn && QCoilHeatSP > SmallLoad && @@ -2692,7 +2692,7 @@ namespace FanCoilUnits { } } } - CalcZoneSensibleOutput(AirMassFlow, Node(OutletNode).Temp, Node(InletNode).Temp, Node(InletNode).HumRat, QUnitOut); + QUnitOut = calcZoneSensibleOutput(AirMassFlow, Node(OutletNode).Temp, Node(InletNode).Temp, Node(InletNode).HumRat); } else { // no action QUnitOut = QUnitOutNoHC; @@ -3346,7 +3346,7 @@ namespace FanCoilUnits { SpecHumOut = Node(OutletNode).HumRat; SpecHumIn = Node(InletNode).HumRat; LatentOutput = AirMassFlow * (SpecHumOut - SpecHumIn); // Latent rate (kg/s), dehumid = negative - CalcZoneSensibleOutput(AirMassFlow, Node(OutletNode).Temp, Node(InletNode).Temp, Node(InletNode).HumRat, QSensUnitOutNoATM); + QSensUnitOutNoATM = calcZoneSensibleOutput(AirMassFlow, Node(OutletNode).Temp, Node(InletNode).Temp, Node(InletNode).HumRat); QTotUnitOut = AirMassFlow * (Node(OutletNode).Enthalpy - Node(InletNode).Enthalpy); // report variables FanCoil(FanCoilNum).HeatPower = max(0.0, QSensUnitOutNoATM); @@ -3369,7 +3369,7 @@ namespace FanCoilUnits { SpecHumOut = Node(OutletNode).HumRat; SpecHumIn = Node(InletNode).HumRat; LatentOutput = AirMassFlow * (SpecHumOut - SpecHumIn); // Latent rate (kg/s), dehumid = negative - CalcZoneSensibleOutput(AirMassFlow, Node(OutletNode).Temp, Node(InletNode).Temp, Node(InletNode).HumRat, QSensUnitOutNoATM); + QSensUnitOutNoATM = calcZoneSensibleOutput(AirMassFlow, Node(OutletNode).Temp, Node(InletNode).Temp, Node(InletNode).HumRat); QTotUnitOut = AirMassFlow * (Node(OutletNode).Enthalpy - Node(InletNode).Enthalpy); // report variables FanCoil(FanCoilNum).HeatPower = max(0.0, QSensUnitOutNoATM); @@ -3847,21 +3847,17 @@ namespace FanCoilUnits { if (FanCoil(FanCoilNum).ATMixerType == ATMixer_SupplySide) { // Now calculate the ATM mixer if it is on the supply side of the zone unit SimATMixer(state, FanCoil(FanCoilNum).ATMixerName, FirstHVACIteration, FanCoil(FanCoilNum).ATMixerIndex); - CalcZoneSensibleOutput(Node(state.dataFanCoilUnits->ATMixOutNode).MassFlowRate, - Node(state.dataFanCoilUnits->ATMixOutNode).Temp, - Node(state.dataFanCoilUnits->ZoneNode).Temp, - Node(state.dataFanCoilUnits->ZoneNode).HumRat, - LoadMet); + LoadMet = calcZoneSensibleOutput(Node(state.dataFanCoilUnits->ATMixOutNode).MassFlowRate, + Node(state.dataFanCoilUnits->ATMixOutNode).Temp, + Node(state.dataFanCoilUnits->ZoneNode).Temp, + Node(state.dataFanCoilUnits->ZoneNode).HumRat); } else { // ATM Mixer on inlet side - CalcZoneSensibleOutput(AirMassFlow, - Node(OutletNode).Temp, - Node(state.dataFanCoilUnits->ZoneNode).Temp, - Node(state.dataFanCoilUnits->ZoneNode).HumRat, - LoadMet); + LoadMet = calcZoneSensibleOutput( + AirMassFlow, Node(OutletNode).Temp, Node(state.dataFanCoilUnits->ZoneNode).Temp, Node(state.dataFanCoilUnits->ZoneNode).HumRat); } } else { - CalcZoneSensibleOutput(AirMassFlow, Node(OutletNode).Temp, Node(InletNode).Temp, Node(InletNode).HumRat, LoadMet); + LoadMet = calcZoneSensibleOutput(AirMassFlow, Node(OutletNode).Temp, Node(InletNode).Temp, Node(InletNode).HumRat); } } diff --git a/src/EnergyPlus/FuelCellElectricGenerator.cc b/src/EnergyPlus/FuelCellElectricGenerator.cc index dc69baa5912..7f61e65b688 100644 --- a/src/EnergyPlus/FuelCellElectricGenerator.cc +++ b/src/EnergyPlus/FuelCellElectricGenerator.cc @@ -60,7 +60,6 @@ #include #include #include -#include #include #include #include @@ -76,6 +75,7 @@ #include #include #include +#include namespace EnergyPlus { @@ -2045,7 +2045,8 @@ namespace FuelCellElectricGenerator { // get zone air temp if (this->FCPM.ZoneID > 0) { - this->FCPM.QdotSkin = this->FCPM.UAskin * (this->FCPM.TprodGasLeavingFCPM - state.dataHeatBalFanSys->ZT(this->FCPM.ZoneID)); + this->FCPM.QdotSkin = this->FCPM.UAskin * (this->FCPM.TprodGasLeavingFCPM - + state.dataZoneTempPredictorCorrector->zoneHeatBalance(this->FCPM.ZoneID).ZT); } } else if (this->FCPM.SkinLossMode == DataGenerators::SkinLoss::QuadraticFuelNdot) { diff --git a/src/EnergyPlus/Furnaces.cc b/src/EnergyPlus/Furnaces.cc index c1641d46d78..384d956e031 100644 --- a/src/EnergyPlus/Furnaces.cc +++ b/src/EnergyPlus/Furnaces.cc @@ -91,6 +91,7 @@ #include #include #include +#include namespace EnergyPlus { @@ -7373,10 +7374,14 @@ namespace Furnaces { if (state.dataDXCoils->DXCoil(state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex) .IsSecondaryDXCoilInZone) { // assumes compressor is in same location as secondary coil OutdoorDryBulbTemp = - state.dataHeatBalFanSys->ZT(state.dataDXCoils->DXCoil(state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex).SecZonePtr); + state.dataZoneTempPredictorCorrector + ->zoneHeatBalance(state.dataDXCoils->DXCoil(state.dataFurnaces->Furnace(FurnaceNum).HeatingCoilIndex).SecZonePtr) + .ZT; } else if (state.dataDXCoils->DXCoil(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).IsSecondaryDXCoilInZone) { OutdoorDryBulbTemp = - state.dataHeatBalFanSys->ZT(state.dataDXCoils->DXCoil(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).SecZonePtr); + state.dataZoneTempPredictorCorrector + ->zoneHeatBalance(state.dataDXCoils->DXCoil(state.dataFurnaces->Furnace(FurnaceNum).CoolingCoilIndex).SecZonePtr) + .ZT; } else { if (state.dataFurnaces->Furnace(FurnaceNum).CondenserNodeNum > 0) { OutdoorDryBulbTemp = state.dataLoopNodes->Node(state.dataFurnaces->Furnace(FurnaceNum).CondenserNodeNum).Temp; diff --git a/src/EnergyPlus/GeneralRoutines.cc b/src/EnergyPlus/GeneralRoutines.cc index 5fcb2eba865..f1608d1fb54 100644 --- a/src/EnergyPlus/GeneralRoutines.cc +++ b/src/EnergyPlus/GeneralRoutines.cc @@ -2106,11 +2106,10 @@ void CalcZoneSensibleLatentOutput(Real64 const MassFlow, // air mass flow rate, } } -void CalcZoneSensibleOutput(Real64 const MassFlow, // air mass flow rate, {kg/s} - Real64 const TDBEquip, // dry-bulb temperature at equipment outlet {C} - Real64 const TDBZone, // dry-bulb temperature at zone air node {C} - Real64 const WZone, // humidity ratio at zone air node - Real64 &SensibleOutput // sensible output rate (state 2 -> State 1), {W} +Real64 calcZoneSensibleOutput(Real64 const MassFlow, // air mass flow rate, {kg/s} + Real64 const TDBEquip, // dry-bulb temperature at equipment outlet {C} + Real64 const TDBZone, // dry-bulb temperature at zone air node {C} + Real64 const WZone // humidity ratio at zone air node ) { @@ -2124,9 +2123,10 @@ void CalcZoneSensibleOutput(Real64 const MassFlow, // air mass flow rate, {kg/s} // or Q_sensible = m_dot * cp_moistair_zoneHumRat * (TDBEquip - TDBZone) // cp_moistair_zoneHumRat = Psychrometrics::PsyCpAirFnW(WZone); - SensibleOutput = 0.0; + Real64 sensibleOutput = 0.0; // sensible output rate (state 2 -> State 1), {W} if (MassFlow > 0.0) { - SensibleOutput = MassFlow * Psychrometrics::PsyDeltaHSenFnTdb2Tdb1W(TDBEquip, TDBZone, WZone); // sensible addition/removal rate, {W}; + sensibleOutput = MassFlow * Psychrometrics::PsyDeltaHSenFnTdb2Tdb1W(TDBEquip, TDBZone, WZone); // sensible addition/removal rate, {W}; } + return sensibleOutput; } } // namespace EnergyPlus diff --git a/src/EnergyPlus/GeneralRoutines.hh b/src/EnergyPlus/GeneralRoutines.hh index 9e4d3f2a023..42686484ec2 100644 --- a/src/EnergyPlus/GeneralRoutines.hh +++ b/src/EnergyPlus/GeneralRoutines.hh @@ -242,12 +242,10 @@ void CalcZoneSensibleLatentOutput(Real64 const MassFlow, // air mass flow rate, Real64 &TotalOutput // total = sensible + latent putput rate (state 2 -> State 1), {W} ); -void CalcZoneSensibleOutput(Real64 const MassFlow, // air mass flow rate, {kg/s} - Real64 const TDBEquip, // dry-bulb temperature at equipment outlet {C} - Real64 const TDBZone, // dry-bulb temperature at zone air node {C} - Real64 const WZone, // humidity ratio at zone air node - Real64 &SensibleOutput // sensible output rate (state 2 -> State 1), {W} -); +Real64 calcZoneSensibleOutput(Real64 const MassFlow, // air mass flow rate, {kg/s} + Real64 const TDBEquip, // dry-bulb temperature at equipment outlet {C} + Real64 const TDBZone, // dry-bulb temperature at zone air node {C} + Real64 const WZone); struct GeneralRoutinesData : BaseGlobalStruct { diff --git a/src/EnergyPlus/HVACManager.cc b/src/EnergyPlus/HVACManager.cc index f8dfdc7d1bd..fd0318485be 100644 --- a/src/EnergyPlus/HVACManager.cc +++ b/src/EnergyPlus/HVACManager.cc @@ -68,6 +68,7 @@ #include #include #include +#include #include #include #include @@ -200,12 +201,22 @@ void ManageHVAC(EnergyPlusData &state) state.afn->manage_balance(); // first call only gets input and returns. } - state.dataHeatBalFanSys->ZT = state.dataHeatBalFanSys->MAT; - // save for use with thermal comfort control models (Fang, Pierce, and KSU) - state.dataHeatBalFanSys->ZTAV = 0.0; + for (auto &thisZoneHB : state.dataZoneTempPredictorCorrector->zoneHeatBalance) { + thisZoneHB.ZT = thisZoneHB.MAT; + // save for use with thermal comfort control models (Fang, Pierce, and KSU) + thisZoneHB.ZTAV = 0.0; + thisZoneHB.ZoneAirHumRatAvg = 0.0; + } + if (state.dataHeatBal->doSpaceHeatBalance) { + for (auto &thisSpaceHB : state.dataZoneTempPredictorCorrector->spaceHeatBalance) { + thisSpaceHB.ZT = thisSpaceHB.MAT; + // save for use with thermal comfort control models (Fang, Pierce, and KSU) + thisSpaceHB.ZTAV = 0.0; + thisSpaceHB.ZoneAirHumRatAvg = 0.0; + } + } state.dataHeatBalFanSys->ZoneThermostatSetPointHiAver = 0.0; state.dataHeatBalFanSys->ZoneThermostatSetPointLoAver = 0.0; - state.dataHeatBalFanSys->ZoneAirHumRatAvg = 0.0; state.dataHVACMgr->PrintedWarmup = false; if (state.dataContaminantBalance->Contaminant.CO2Simulation) { state.dataContaminantBalance->OutdoorCO2 = GetCurrentScheduleValue(state, state.dataContaminantBalance->Contaminant.CO2OutdoorSchedPtr); @@ -265,7 +276,17 @@ void ManageHVAC(EnergyPlusData &state) SetHeatToReturnAirFlag(state); - state.dataHeatBalFanSys->SysDepZoneLoadsLagged = state.dataHeatBalFanSys->SysDepZoneLoads; + for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum); + thisZoneHB.SysDepZoneLoadsLagged = thisZoneHB.SysDepZoneLoads; + if (state.dataHeatBal->doSpaceHeatBalance) { + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + // SpaceHB ToDo: For now allocate by space volume frac + state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).SysDepZoneLoadsLagged = + thisZoneHB.SysDepZoneLoads * state.dataHeatBal->space(spaceNum).fracZoneVolume; + } + } + } UpdateInternalGainValues(state, true, true); @@ -382,8 +403,16 @@ void ManageHVAC(EnergyPlusData &state) FracTimeStepZone = TimeStepSys / state.dataGlobal->TimeStepZone; for (ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { - state.dataHeatBalFanSys->ZTAV(ZoneNum) += state.dataHeatBalFanSys->ZT(ZoneNum) * FracTimeStepZone; - state.dataHeatBalFanSys->ZoneAirHumRatAvg(ZoneNum) += state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum) * FracTimeStepZone; + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); + thisZoneHB.ZTAV += thisZoneHB.ZT * FracTimeStepZone; + thisZoneHB.ZoneAirHumRatAvg += thisZoneHB.ZoneAirHumRat * FracTimeStepZone; + if (state.dataHeatBal->doSpaceHeatBalance) { + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum); + thisSpaceHB.ZTAV += thisSpaceHB.ZT * FracTimeStepZone; + thisSpaceHB.ZoneAirHumRatAvg += thisSpaceHB.ZoneAirHumRat * FracTimeStepZone; + } + } if (state.dataContaminantBalance->Contaminant.CO2Simulation) state.dataContaminantBalance->ZoneAirCO2Avg(ZoneNum) += state.dataContaminantBalance->ZoneAirCO2(ZoneNum) * FracTimeStepZone; if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) @@ -527,8 +556,16 @@ void ManageHVAC(EnergyPlusData &state) FirstTimeStepSysFlag = false; } // system time step loop (loops once if no downstepping) - state.dataHeatBalFanSys->ZTAVComf = state.dataHeatBalFanSys->ZTAV; - state.dataHeatBalFanSys->ZoneAirHumRatAvgComf = state.dataHeatBalFanSys->ZoneAirHumRatAvg; + for (auto &thisZoneHB : state.dataZoneTempPredictorCorrector->zoneHeatBalance) { + thisZoneHB.ZTAVComf = thisZoneHB.ZTAV; + thisZoneHB.ZoneAirHumRatAvgComf = thisZoneHB.ZoneAirHumRatAvg; + } + if (state.dataHeatBal->doSpaceHeatBalance) { + for (auto &thisSpaceHB : state.dataZoneTempPredictorCorrector->spaceHeatBalance) { + thisSpaceHB.ZTAVComf = thisSpaceHB.ZTAV; + thisSpaceHB.ZoneAirHumRatAvgComf = thisSpaceHB.ZoneAirHumRatAvg; + } + } ManageZoneAirUpdates(state, DataHeatBalFanSys::PredictorCorrectorCtrl::PushZoneTimestepHistories, @@ -2254,10 +2291,14 @@ void UpdateZoneListAndGroupLoads(EnergyPlusData &state) for (ListNum = 1; ListNum <= state.dataHeatBal->NumOfZoneLists; ++ListNum) { for (ZoneNum = 1; ZoneNum <= ZoneList(ListNum).NumOfZones; ++ZoneNum) { Mult = state.dataHeatBal->Zone(ZoneNum).Multiplier; - ZoneListSNLoadHeatEnergy(ListNum) += state.dataHeatBal->ZoneSNLoadHeatEnergy(ZoneList(ListNum).Zone(ZoneNum)) * Mult; - ZoneListSNLoadCoolEnergy(ListNum) += state.dataHeatBal->ZoneSNLoadCoolEnergy(ZoneList(ListNum).Zone(ZoneNum)) * Mult; - ZoneListSNLoadHeatRate(ListNum) += state.dataHeatBal->ZoneSNLoadHeatRate(ZoneList(ListNum).Zone(ZoneNum)) * Mult; - ZoneListSNLoadCoolRate(ListNum) += state.dataHeatBal->ZoneSNLoadCoolRate(ZoneList(ListNum).Zone(ZoneNum)) * Mult; + ZoneListSNLoadHeatEnergy(ListNum) += + state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneList(ListNum).Zone(ZoneNum)).ZoneSNLoadHeatEnergy * Mult; + ZoneListSNLoadCoolEnergy(ListNum) += + state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneList(ListNum).Zone(ZoneNum)).ZoneSNLoadCoolEnergy * Mult; + ZoneListSNLoadHeatRate(ListNum) += + state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneList(ListNum).Zone(ZoneNum)).ZoneSNLoadHeatRate * Mult; + ZoneListSNLoadCoolRate(ListNum) += + state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneList(ListNum).Zone(ZoneNum)).ZoneSNLoadCoolRate * Mult; } // ZoneNum } // ListNum @@ -2288,8 +2329,6 @@ void ReportInfiltrations(EnergyPlusData &state) using Psychrometrics::PsyCpAirFnW; using Psychrometrics::PsyHgAirFnWTdb; using Psychrometrics::PsyRhoAirFnPbTdbW; - int j; // Loop Counter - int NZ; // A pointer // SUBROUTINE PARAMETER DEFINITIONS: static std::string const RoutineName("ReportInfiltrations"); @@ -2299,13 +2338,13 @@ void ReportInfiltrations(EnergyPlusData &state) Real64 TotalLoad; // Total loss or gain Real64 H2OHtOfVap; // Heat of vaporization of air Real64 ADSCorrectionFactor; // Correction factor of air flow model values when ADS is simulated - auto &Zone(state.dataHeatBal->Zone); - auto &Infiltration(state.dataHeatBal->Infiltration); - auto &TimeStepSys(state.dataHVACGlobal->TimeStepSys); + Real64 TimeStepSys = state.dataHVACGlobal->TimeStepSys; - for (j = 1; j <= state.dataHeatBal->TotInfiltration; ++j) { + for (auto &thisInfiltration : state.dataHeatBal->Infiltration) { - NZ = state.dataHeatBal->Infiltration(j).ZonePtr; + int NZ = thisInfiltration.ZonePtr; + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ); + auto &thisZone = state.dataHeatBal->Zone(NZ); ADSCorrectionFactor = 1.0; if (state.afn->simulation_control.type == AirflowNetwork::ControlType::MultizoneWithDistributionOnlyDuringFanOperation) { // CR7608 IF (TurnFansOn .AND. AirflowNetworkZoneFlag(NZ)) ADSCorrectionFactor=0 @@ -2315,56 +2354,56 @@ void ReportInfiltrations(EnergyPlusData &state) } CpAir = PsyCpAirFnW(state.dataEnvrn->OutHumRat); - Infiltration(j).InfilMdot = Infiltration(j).MCpI_temp / CpAir * ADSCorrectionFactor; - Infiltration(j).InfilMass = Infiltration(j).InfilMdot * TimeStepSys * DataGlobalConstants::SecInHour; + thisInfiltration.InfilMdot = thisInfiltration.MCpI_temp / CpAir * ADSCorrectionFactor; + thisInfiltration.InfilMass = thisInfiltration.InfilMdot * TimeStepSys * DataGlobalConstants::SecInHour; - if (state.dataHeatBalFanSys->MAT(NZ) > Zone(NZ).OutDryBulbTemp) { + if (thisZoneHB.MAT > thisZone.OutDryBulbTemp) { - Infiltration(j).InfilHeatLoss = Infiltration(j).MCpI_temp * (state.dataHeatBalFanSys->MAT(NZ) - Zone(NZ).OutDryBulbTemp) * TimeStepSys * - DataGlobalConstants::SecInHour * ADSCorrectionFactor; - Infiltration(j).InfilHeatGain = 0.0; + thisInfiltration.InfilHeatLoss = thisInfiltration.MCpI_temp * (thisZoneHB.MAT - thisZone.OutDryBulbTemp) * TimeStepSys * + DataGlobalConstants::SecInHour * ADSCorrectionFactor; + thisInfiltration.InfilHeatGain = 0.0; - } else if (state.dataHeatBalFanSys->MAT(NZ) <= Zone(NZ).OutDryBulbTemp) { + } else if (thisZoneHB.MAT <= thisZone.OutDryBulbTemp) { - Infiltration(j).InfilHeatGain = Infiltration(j).MCpI_temp * (Zone(NZ).OutDryBulbTemp - state.dataHeatBalFanSys->MAT(NZ)) * TimeStepSys * - DataGlobalConstants::SecInHour * ADSCorrectionFactor; - Infiltration(j).InfilHeatLoss = 0.0; + thisInfiltration.InfilHeatGain = thisInfiltration.MCpI_temp * (thisZone.OutDryBulbTemp - thisZoneHB.MAT) * TimeStepSys * + DataGlobalConstants::SecInHour * ADSCorrectionFactor; + thisInfiltration.InfilHeatLoss = 0.0; } // Report infiltration latent gains and losses - H2OHtOfVap = PsyHgAirFnWTdb(state.dataHeatBalFanSys->ZoneAirHumRat(NZ), state.dataHeatBalFanSys->MAT(NZ)); - if (state.dataHeatBalFanSys->ZoneAirHumRat(NZ) > state.dataEnvrn->OutHumRat) { + H2OHtOfVap = PsyHgAirFnWTdb(thisZoneHB.ZoneAirHumRat, thisZoneHB.MAT); + if (thisZoneHB.ZoneAirHumRat > state.dataEnvrn->OutHumRat) { - Infiltration(j).InfilLatentLoss = Infiltration(j).InfilMdot * (state.dataHeatBalFanSys->ZoneAirHumRat(NZ) - state.dataEnvrn->OutHumRat) * - H2OHtOfVap * TimeStepSys * DataGlobalConstants::SecInHour; - Infiltration(j).InfilLatentGain = 0.0; + thisInfiltration.InfilLatentLoss = thisInfiltration.InfilMdot * (thisZoneHB.ZoneAirHumRat - state.dataEnvrn->OutHumRat) * H2OHtOfVap * + TimeStepSys * DataGlobalConstants::SecInHour; + thisInfiltration.InfilLatentGain = 0.0; - } else if (state.dataHeatBalFanSys->ZoneAirHumRat(NZ) <= state.dataEnvrn->OutHumRat) { + } else if (thisZoneHB.ZoneAirHumRat <= state.dataEnvrn->OutHumRat) { - Infiltration(j).InfilLatentGain = Infiltration(j).InfilMdot * (state.dataEnvrn->OutHumRat - state.dataHeatBalFanSys->ZoneAirHumRat(NZ)) * - H2OHtOfVap * TimeStepSys * DataGlobalConstants::SecInHour; - Infiltration(j).InfilLatentLoss = 0.0; + thisInfiltration.InfilLatentGain = thisInfiltration.InfilMdot * (state.dataEnvrn->OutHumRat - thisZoneHB.ZoneAirHumRat) * H2OHtOfVap * + TimeStepSys * DataGlobalConstants::SecInHour; + thisInfiltration.InfilLatentLoss = 0.0; } // Total infiltration losses and gains - TotalLoad = Infiltration(j).InfilHeatGain + Infiltration(j).InfilLatentGain - Infiltration(j).InfilHeatLoss - Infiltration(j).InfilLatentLoss; + TotalLoad = + thisInfiltration.InfilHeatGain + thisInfiltration.InfilLatentGain - thisInfiltration.InfilHeatLoss - thisInfiltration.InfilLatentLoss; if (TotalLoad > 0) { - Infiltration(j).InfilTotalGain = TotalLoad; - Infiltration(j).InfilTotalLoss = 0.0; + thisInfiltration.InfilTotalGain = TotalLoad; + thisInfiltration.InfilTotalLoss = 0.0; } else { - Infiltration(j).InfilTotalGain = 0.0; - Infiltration(j).InfilTotalLoss = -TotalLoad; + thisInfiltration.InfilTotalGain = 0.0; + thisInfiltration.InfilTotalLoss = -TotalLoad; } // CR7751 second, calculate using indoor conditions for density property - AirDensity = PsyRhoAirFnPbTdbW( - state, state.dataEnvrn->OutBaroPress, state.dataHeatBalFanSys->MAT(NZ), state.dataHeatBalFanSys->ZoneAirHumRatAvg(NZ), RoutineName); - Infiltration(j).InfilVdotCurDensity = Infiltration(j).InfilMdot / AirDensity; - Infiltration(j).InfilVolumeCurDensity = Infiltration(j).InfilVdotCurDensity * TimeStepSys * DataGlobalConstants::SecInHour; - Infiltration(j).InfilAirChangeRate = Infiltration(j).InfilVolumeCurDensity / (TimeStepSys * Zone(NZ).Volume); + AirDensity = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, thisZoneHB.MAT, thisZoneHB.ZoneAirHumRatAvg, RoutineName); + thisInfiltration.InfilVdotCurDensity = thisInfiltration.InfilMdot / AirDensity; + thisInfiltration.InfilVolumeCurDensity = thisInfiltration.InfilVdotCurDensity * TimeStepSys * DataGlobalConstants::SecInHour; + thisInfiltration.InfilAirChangeRate = thisInfiltration.InfilVolumeCurDensity / (TimeStepSys * thisZone.Volume); // CR7751 third, calculate using standard dry air at nominal elevation AirDensity = state.dataEnvrn->StdRhoAir; - Infiltration(j).InfilVdotStdDensity = Infiltration(j).InfilMdot / AirDensity; - Infiltration(j).InfilVolumeStdDensity = Infiltration(j).InfilVdotStdDensity * TimeStepSys * DataGlobalConstants::SecInHour; + thisInfiltration.InfilVdotStdDensity = thisInfiltration.InfilMdot / AirDensity; + thisInfiltration.InfilVolumeStdDensity = thisInfiltration.InfilVdotStdDensity * TimeStepSys * DataGlobalConstants::SecInHour; } } @@ -2375,7 +2414,6 @@ void ReportAirHeatBalance(EnergyPlusData &state) // AUTHOR Linda Lawrie // DATE WRITTEN July 2000 // MODIFIED Shirey, Jan 2008 (MIXING/CROSS MIXING outputs) - // RE-ENGINEERED na // PURPOSE OF THIS SUBROUTINE: // This subroutine updates the report variables for the AirHeatBalance. @@ -2388,27 +2426,16 @@ void ReportAirHeatBalance(EnergyPlusData &state) using Psychrometrics::PsyHgAirFnWTdb; using Psychrometrics::PsyRhoAirFnPbTdbW; - // SUBROUTINE PARAMETER DEFINITIONS: static constexpr std::string_view RoutineName3("ReportAirHeatBalance:3"); // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int ZoneLoop; // Counter for the # of zones (nz) - int ZoneA; // Mated zone number for pair pf zones sharing refrigeration door opening - int ZoneB; // Mated zone number for pair pf zones sharing refrigeration door opening - int VentNum; // Counter for ventilation statements - int FanNum; // Counter for exhaust fans Real64 AirDensity; // Density of air (kg/m^3) Real64 CpAir; // Heat capacity of air (J/kg-C) Real64 ADSCorrectionFactor; // Correction factor of air flow model values when ADS is simulated Real64 H2OHtOfVap; // Heat of vaporization of air Real64 TotalLoad; // Total loss or gain - int MixNum; // Counter for MIXING and Cross Mixing statements auto &MixSenLoad = state.dataHVACMgr->MixSenLoad; // Mixing sensible loss or gain auto &MixLatLoad = state.dataHVACMgr->MixLatLoad; // Mixing latent loss or gain - int j; // Index in a do-loop - int VentZoneNum; // Number of ventilation object per zone - Real64 VentZoneMassflow; // Total mass flow rate per zone - Real64 VentZoneAirTemp; // Average Zone inlet temperature state.dataHeatBal->ZoneTotalExfiltrationHeatLoss = 0.0; state.dataHeatBal->ZoneTotalExhaustHeatLoss = 0.0; @@ -2428,7 +2455,7 @@ void ReportAirHeatBalance(EnergyPlusData &state) } // Reports zone exhaust loss by exhaust fans - for (ZoneLoop = 1; ZoneLoop <= state.dataGlobal->NumOfZones; ++ZoneLoop) { // Start of zone loads report variable update loop ... + for (int ZoneLoop = 1; ZoneLoop <= state.dataGlobal->NumOfZones; ++ZoneLoop) { // Start of zone loads report variable update loop ... CpAir = PsyCpAirFnW(state.dataEnvrn->OutHumRat); H2OHtOfVap = PsyHgAirFnWTdb(state.dataEnvrn->OutHumRat, Zone(ZoneLoop).OutDryBulbTemp); ADSCorrectionFactor = 1.0; @@ -2442,7 +2469,7 @@ void ReportAirHeatBalance(EnergyPlusData &state) ZnAirRpt(ZoneLoop).ExhTotalLoss = 0; ZnAirRpt(ZoneLoop).ExhSensiLoss = 0; - for (FanNum = 1; FanNum <= state.dataFans->NumFans; ++FanNum) { + for (int FanNum = 1; FanNum <= state.dataFans->NumFans; ++FanNum) { // Add reportable vars if (Fan(FanNum).FanType_Num == FanType_ZoneExhaust) { for (int ExhNum = 1; ExhNum <= ZoneEquipConfig(ZoneLoop).NumExhaustNodes; ExhNum++) { @@ -2474,7 +2501,8 @@ void ReportAirHeatBalance(EnergyPlusData &state) ReportInfiltrations(state); - for (ZoneLoop = 1; ZoneLoop <= state.dataGlobal->NumOfZones; ++ZoneLoop) { // Start of zone loads report variable update loop ... + for (int ZoneLoop = 1; ZoneLoop <= state.dataGlobal->NumOfZones; ++ZoneLoop) { // Start of zone loads report variable update loop ... + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneLoop); // Break the infiltration load into heat gain and loss components ADSCorrectionFactor = 1.0; @@ -2486,34 +2514,30 @@ void ReportAirHeatBalance(EnergyPlusData &state) ADSCorrectionFactor = 0.0; } - if (state.dataHeatBalFanSys->MAT(ZoneLoop) > Zone(ZoneLoop).OutDryBulbTemp) { + if (thisZoneHB.MAT > Zone(ZoneLoop).OutDryBulbTemp) { - ZnAirRpt(ZoneLoop).InfilHeatLoss = state.dataHeatBalFanSys->MCPI(ZoneLoop) * - (state.dataHeatBalFanSys->MAT(ZoneLoop) - Zone(ZoneLoop).OutDryBulbTemp) * TimeStepSys * + ZnAirRpt(ZoneLoop).InfilHeatLoss = thisZoneHB.MCPI * (thisZoneHB.MAT - Zone(ZoneLoop).OutDryBulbTemp) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).InfilHeatGain = 0.0; - } else if (state.dataHeatBalFanSys->MAT(ZoneLoop) <= Zone(ZoneLoop).OutDryBulbTemp) { + } else if (thisZoneHB.MAT <= Zone(ZoneLoop).OutDryBulbTemp) { - ZnAirRpt(ZoneLoop).InfilHeatGain = state.dataHeatBalFanSys->MCPI(ZoneLoop) * - (Zone(ZoneLoop).OutDryBulbTemp - state.dataHeatBalFanSys->MAT(ZoneLoop)) * TimeStepSys * + ZnAirRpt(ZoneLoop).InfilHeatGain = thisZoneHB.MCPI * (Zone(ZoneLoop).OutDryBulbTemp - thisZoneHB.MAT) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).InfilHeatLoss = 0.0; } // Report infiltration latent gains and losses CpAir = PsyCpAirFnW(state.dataEnvrn->OutHumRat); - H2OHtOfVap = PsyHgAirFnWTdb(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop), state.dataHeatBalFanSys->MAT(ZoneLoop)); - if (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) > state.dataEnvrn->OutHumRat) { + H2OHtOfVap = PsyHgAirFnWTdb(thisZoneHB.ZoneAirHumRat, thisZoneHB.MAT); + if (thisZoneHB.ZoneAirHumRat > state.dataEnvrn->OutHumRat) { - ZnAirRpt(ZoneLoop).InfilLatentLoss = state.dataHeatBalFanSys->MCPI(ZoneLoop) / CpAir * - (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) - state.dataEnvrn->OutHumRat) * H2OHtOfVap * + ZnAirRpt(ZoneLoop).InfilLatentLoss = thisZoneHB.MCPI / CpAir * (thisZoneHB.ZoneAirHumRat - state.dataEnvrn->OutHumRat) * H2OHtOfVap * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).InfilLatentGain = 0.0; - } else if (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) <= state.dataEnvrn->OutHumRat) { + } else if (thisZoneHB.ZoneAirHumRat <= state.dataEnvrn->OutHumRat) { - ZnAirRpt(ZoneLoop).InfilLatentGain = state.dataHeatBalFanSys->MCPI(ZoneLoop) / CpAir * - (state.dataEnvrn->OutHumRat - state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop)) * H2OHtOfVap * + ZnAirRpt(ZoneLoop).InfilLatentGain = thisZoneHB.MCPI / CpAir * (state.dataEnvrn->OutHumRat - thisZoneHB.ZoneAirHumRat) * H2OHtOfVap * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).InfilLatentLoss = 0.0; } @@ -2529,17 +2553,13 @@ void ReportAirHeatBalance(EnergyPlusData &state) } // first calculate mass flows using outside air heat capacity for consistency with input to heat balance - ZnAirRpt(ZoneLoop).InfilMdot = (state.dataHeatBalFanSys->MCPI(ZoneLoop) / CpAir) * ADSCorrectionFactor; + ZnAirRpt(ZoneLoop).InfilMdot = (thisZoneHB.MCPI / CpAir) * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).InfilMass = ZnAirRpt(ZoneLoop).InfilMdot * TimeStepSys * DataGlobalConstants::SecInHour; - ZnAirRpt(ZoneLoop).VentilMdot = (state.dataHeatBalFanSys->MCPV(ZoneLoop) / CpAir) * ADSCorrectionFactor; + ZnAirRpt(ZoneLoop).VentilMdot = (thisZoneHB.MCPV / CpAir) * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).VentilMass = ZnAirRpt(ZoneLoop).VentilMdot * TimeStepSys * DataGlobalConstants::SecInHour; // CR7751 second, calculate using indoor conditions for density property - AirDensity = PsyRhoAirFnPbTdbW(state, - state.dataEnvrn->OutBaroPress, - state.dataHeatBalFanSys->MAT(ZoneLoop), - state.dataHeatBalFanSys->ZoneAirHumRatAvg(ZoneLoop), - RoutineName3); + AirDensity = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, thisZoneHB.MAT, thisZoneHB.ZoneAirHumRatAvg, RoutineName3); ZnAirRpt(ZoneLoop).InfilVdotCurDensity = ZnAirRpt(ZoneLoop).InfilMdot / AirDensity; ZnAirRpt(ZoneLoop).InfilVolumeCurDensity = ZnAirRpt(ZoneLoop).InfilVdotCurDensity * TimeStepSys * DataGlobalConstants::SecInHour; ZnAirRpt(ZoneLoop).InfilAirChangeRate = ZnAirRpt(ZoneLoop).InfilVolumeCurDensity / (TimeStepSys * Zone(ZoneLoop).Volume); @@ -2558,11 +2578,11 @@ void ReportAirHeatBalance(EnergyPlusData &state) ZnAirRpt(ZoneLoop).VentilAirTemp = 0.0; ZnAirRpt(ZoneLoop).VentilHeatLoss = 0.0; ZnAirRpt(ZoneLoop).VentilHeatGain = 0.0; - VentZoneNum = 0; - VentZoneMassflow = 0.0; - VentZoneAirTemp = 0.0; + int VentZoneNum = 0; // Number of ventilation object per zone + Real64 VentZoneMassflow = 0.0; // Total mass flow rate per zone + Real64 VentZoneAirTemp = 0.0; // Average Zone inlet temperature - for (VentNum = 1; VentNum <= state.dataHeatBal->TotVentilation; ++VentNum) { + for (int VentNum = 1; VentNum <= state.dataHeatBal->TotVentilation; ++VentNum) { if (Ventilation(VentNum).ZonePtr == ZoneLoop) { // moved into CalcAirFlowSimple // ZnAirRpt(ZoneLoop)%VentilFanElec = @@ -2570,20 +2590,18 @@ void ReportAirHeatBalance(EnergyPlusData &state) // & // *ADSCorrectionFactor if (ADSCorrectionFactor > 0) { - ZnAirRpt(ZoneLoop).VentilAirTemp += Ventilation(VentNum).AirTemp * state.dataZoneEquip->VentMCP(VentNum); - VentZoneMassflow += state.dataZoneEquip->VentMCP(VentNum); + ZnAirRpt(ZoneLoop).VentilAirTemp += Ventilation(VentNum).AirTemp * Ventilation(VentNum).MCP; + VentZoneMassflow += Ventilation(VentNum).MCP; VentZoneAirTemp += Ventilation(VentNum).AirTemp; } else { ZnAirRpt(ZoneLoop).VentilAirTemp = Zone(ZoneLoop).OutDryBulbTemp; } // Break the ventilation load into heat gain and loss components - if (state.dataHeatBalFanSys->MAT(ZoneLoop) > Ventilation(VentNum).AirTemp) { - ZnAirRpt(ZoneLoop).VentilHeatLoss += state.dataZoneEquip->VentMCP(VentNum) * - (state.dataHeatBalFanSys->MAT(ZoneLoop) - Ventilation(VentNum).AirTemp) * TimeStepSys * + if (thisZoneHB.MAT > Ventilation(VentNum).AirTemp) { + ZnAirRpt(ZoneLoop).VentilHeatLoss += Ventilation(VentNum).MCP * (thisZoneHB.MAT - Ventilation(VentNum).AirTemp) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; - } else if (state.dataHeatBalFanSys->MAT(ZoneLoop) <= Ventilation(VentNum).AirTemp) { - ZnAirRpt(ZoneLoop).VentilHeatGain += state.dataZoneEquip->VentMCP(VentNum) * - (Ventilation(VentNum).AirTemp - state.dataHeatBalFanSys->MAT(ZoneLoop)) * TimeStepSys * + } else if (thisZoneHB.MAT <= Ventilation(VentNum).AirTemp) { + ZnAirRpt(ZoneLoop).VentilHeatGain += Ventilation(VentNum).MCP * (Ventilation(VentNum).AirTemp - thisZoneHB.MAT) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; } @@ -2591,15 +2609,13 @@ void ReportAirHeatBalance(EnergyPlusData &state) if (VentZoneNum > 1) continue; // Report ventilation latent gains and losses - H2OHtOfVap = PsyHgAirFnWTdb(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop), state.dataHeatBalFanSys->MAT(ZoneLoop)); - if (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) > state.dataEnvrn->OutHumRat) { - ZnAirRpt(ZoneLoop).VentilLatentLoss = ZnAirRpt(ZoneLoop).VentilMdot * - (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) - state.dataEnvrn->OutHumRat) * + H2OHtOfVap = PsyHgAirFnWTdb(thisZoneHB.ZoneAirHumRat, thisZoneHB.MAT); + if (thisZoneHB.ZoneAirHumRat > state.dataEnvrn->OutHumRat) { + ZnAirRpt(ZoneLoop).VentilLatentLoss = ZnAirRpt(ZoneLoop).VentilMdot * (thisZoneHB.ZoneAirHumRat - state.dataEnvrn->OutHumRat) * H2OHtOfVap * TimeStepSys * DataGlobalConstants::SecInHour; ZnAirRpt(ZoneLoop).VentilLatentGain = 0.0; - } else if (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) <= state.dataEnvrn->OutHumRat) { - ZnAirRpt(ZoneLoop).VentilLatentGain = ZnAirRpt(ZoneLoop).VentilMdot * - (state.dataEnvrn->OutHumRat - state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop)) * + } else if (thisZoneHB.ZoneAirHumRat <= state.dataEnvrn->OutHumRat) { + ZnAirRpt(ZoneLoop).VentilLatentGain = ZnAirRpt(ZoneLoop).VentilMdot * (state.dataEnvrn->OutHumRat - thisZoneHB.ZoneAirHumRat) * H2OHtOfVap * TimeStepSys * DataGlobalConstants::SecInHour; ZnAirRpt(ZoneLoop).VentilLatentLoss = 0.0; } @@ -2634,20 +2650,19 @@ void ReportAirHeatBalance(EnergyPlusData &state) ZnAirRpt(ZoneLoop).MixMdot = 0.0; // ! zero reported mass flow rate prior to summations below // MixingLoad = 0.0d0 - for (MixNum = 1; MixNum <= state.dataHeatBal->TotMixing; ++MixNum) { - if ((Mixing(MixNum).ZonePtr == ZoneLoop) && state.dataZoneEquip->MixingReportFlag(MixNum)) { + for (int MixNum = 1; MixNum <= state.dataHeatBal->TotMixing; ++MixNum) { + if ((Mixing(MixNum).ZonePtr == ZoneLoop) && Mixing(MixNum).ReportFlag) { + auto &fromZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(Mixing(MixNum).FromZone); // MixSenLoad(ZoneLoop) = MixSenLoad(ZoneLoop)+MCPM(ZoneLoop)*MAT(Mixing(MixNum)%FromZone) // H2OHtOfVap = PsyHgAirFnWTdb(ZoneAirHumRat(ZoneLoop), MAT(ZoneLoop)) // Per Jan 17, 2008 conference call, agreed to use average conditions for Rho, Cp and Hfg // and to recalculate the report variable using end of time step temps and humrats - AirDensity = PsyRhoAirFnPbTdbW( - state, - state.dataEnvrn->OutBaroPress, - (state.dataHeatBalFanSys->MAT(ZoneLoop) + state.dataHeatBalFanSys->MAT(Mixing(MixNum).FromZone)) / 2.0, - (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) + state.dataHeatBalFanSys->ZoneAirHumRat(Mixing(MixNum).FromZone)) / 2.0, - std::string()); - CpAir = PsyCpAirFnW( - (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) + state.dataHeatBalFanSys->ZoneAirHumRat(Mixing(MixNum).FromZone)) / 2.0); + AirDensity = PsyRhoAirFnPbTdbW(state, + state.dataEnvrn->OutBaroPress, + (thisZoneHB.MAT + fromZoneHB.MAT) / 2.0, + (thisZoneHB.ZoneAirHumRat + fromZoneHB.ZoneAirHumRat) / 2.0, + std::string()); + CpAir = PsyCpAirFnW((thisZoneHB.ZoneAirHumRat + fromZoneHB.ZoneAirHumRat) / 2.0); ZnAirRpt(ZoneLoop).MixVolume += Mixing(MixNum).DesiredAirFlowRate * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).MixVdotCurDensity += Mixing(MixNum).DesiredAirFlowRate * ADSCorrectionFactor; @@ -2656,32 +2671,27 @@ void ReportAirHeatBalance(EnergyPlusData &state) ZnAirRpt(ZoneLoop).MixMdot += Mixing(MixNum).DesiredAirFlowRate * AirDensity * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).MixVdotStdDensity += Mixing(MixNum).DesiredAirFlowRate * (AirDensity / state.dataEnvrn->StdRhoAir) * ADSCorrectionFactor; - MixSenLoad(ZoneLoop) += Mixing(MixNum).DesiredAirFlowRate * AirDensity * CpAir * - (state.dataHeatBalFanSys->MAT(ZoneLoop) - state.dataHeatBalFanSys->MAT(Mixing(MixNum).FromZone)); - H2OHtOfVap = PsyHgAirFnWTdb( - (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) + state.dataHeatBalFanSys->ZoneAirHumRat(Mixing(MixNum).FromZone)) / 2.0, - (state.dataHeatBalFanSys->MAT(ZoneLoop) + state.dataHeatBalFanSys->MAT(Mixing(MixNum).FromZone)) / 2.0); + MixSenLoad(ZoneLoop) += Mixing(MixNum).DesiredAirFlowRate * AirDensity * CpAir * (thisZoneHB.MAT - fromZoneHB.MAT); + H2OHtOfVap = PsyHgAirFnWTdb((thisZoneHB.ZoneAirHumRat + fromZoneHB.ZoneAirHumRat) / 2.0, (thisZoneHB.MAT + fromZoneHB.MAT) / 2.0); // MixLatLoad(ZoneLoop) = MixLatLoad(ZoneLoop)+MixingMassFlowZone(ZoneLoop)*(ZoneAirHumRat(ZoneLoop)- & // ZoneAirHumRat(Mixing(MixNum)%FromZone))*H2OHtOfVap MixLatLoad(ZoneLoop) += - Mixing(MixNum).DesiredAirFlowRate * AirDensity * - (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) - state.dataHeatBalFanSys->ZoneAirHumRat(Mixing(MixNum).FromZone)) * H2OHtOfVap; + Mixing(MixNum).DesiredAirFlowRate * AirDensity * (thisZoneHB.ZoneAirHumRat - fromZoneHB.ZoneAirHumRat) * H2OHtOfVap; } } - for (MixNum = 1; MixNum <= state.dataHeatBal->TotCrossMixing; ++MixNum) { - if ((CrossMixing(MixNum).ZonePtr == ZoneLoop) && state.dataZoneEquip->CrossMixingReportFlag(MixNum)) { + for (int MixNum = 1; MixNum <= state.dataHeatBal->TotCrossMixing; ++MixNum) { + if ((CrossMixing(MixNum).ZonePtr == ZoneLoop) && CrossMixing(MixNum).ReportFlag) { + auto &fromZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(CrossMixing(MixNum).FromZone); // MixSenLoad(ZoneLoop) = MixSenLoad(ZoneLoop)+MCPM(ZoneLoop)*MAT(CrossMixing(MixNum)%FromZone) // Per Jan 17, 2008 conference call, agreed to use average conditions for Rho, Cp and Hfg // and to recalculate the report variable using end of time step temps and humrats - AirDensity = PsyRhoAirFnPbTdbW( - state, - state.dataEnvrn->OutBaroPress, - (state.dataHeatBalFanSys->MAT(ZoneLoop) + state.dataHeatBalFanSys->MAT(CrossMixing(MixNum).FromZone)) / 2.0, - (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) + state.dataHeatBalFanSys->ZoneAirHumRat(CrossMixing(MixNum).FromZone)) / 2.0, - std::string()); - CpAir = PsyCpAirFnW( - (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) + state.dataHeatBalFanSys->ZoneAirHumRat(CrossMixing(MixNum).FromZone)) / 2.0); + AirDensity = PsyRhoAirFnPbTdbW(state, + state.dataEnvrn->OutBaroPress, + (thisZoneHB.MAT + fromZoneHB.MAT) / 2.0, + (thisZoneHB.ZoneAirHumRat + fromZoneHB.ZoneAirHumRat) / 2.0, + std::string()); + CpAir = PsyCpAirFnW((thisZoneHB.ZoneAirHumRat + fromZoneHB.ZoneAirHumRat) / 2.0); ZnAirRpt(ZoneLoop).MixVolume += CrossMixing(MixNum).DesiredAirFlowRate * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).MixVdotCurDensity += CrossMixing(MixNum).DesiredAirFlowRate * ADSCorrectionFactor; @@ -2690,27 +2700,21 @@ void ReportAirHeatBalance(EnergyPlusData &state) ZnAirRpt(ZoneLoop).MixMdot += CrossMixing(MixNum).DesiredAirFlowRate * AirDensity * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).MixVdotStdDensity += CrossMixing(MixNum).DesiredAirFlowRate * (AirDensity / state.dataEnvrn->StdRhoAir) * ADSCorrectionFactor; - MixSenLoad(ZoneLoop) += CrossMixing(MixNum).DesiredAirFlowRate * AirDensity * CpAir * - (state.dataHeatBalFanSys->MAT(ZoneLoop) - state.dataHeatBalFanSys->MAT(CrossMixing(MixNum).FromZone)); - H2OHtOfVap = PsyHgAirFnWTdb( - (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) + state.dataHeatBalFanSys->ZoneAirHumRat(CrossMixing(MixNum).FromZone)) / 2.0, - (state.dataHeatBalFanSys->MAT(ZoneLoop) + state.dataHeatBalFanSys->MAT(CrossMixing(MixNum).FromZone)) / 2.0); + MixSenLoad(ZoneLoop) += CrossMixing(MixNum).DesiredAirFlowRate * AirDensity * CpAir * (thisZoneHB.MAT - fromZoneHB.MAT); + H2OHtOfVap = PsyHgAirFnWTdb((thisZoneHB.ZoneAirHumRat + fromZoneHB.ZoneAirHumRat) / 2.0, (thisZoneHB.MAT + fromZoneHB.MAT) / 2.0); // MixLatLoad(ZoneLoop) = MixLatLoad(ZoneLoop)+MixingMassFlowZone(ZoneLoop)*(ZoneAirHumRat(ZoneLoop)- & // ZoneAirHumRat(CrossMixing(MixNum)%FromZone))*H2OHtOfVap MixLatLoad(ZoneLoop) += - CrossMixing(MixNum).DesiredAirFlowRate * AirDensity * - (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) - state.dataHeatBalFanSys->ZoneAirHumRat(CrossMixing(MixNum).FromZone)) * - H2OHtOfVap; + CrossMixing(MixNum).DesiredAirFlowRate * AirDensity * (thisZoneHB.ZoneAirHumRat - fromZoneHB.ZoneAirHumRat) * H2OHtOfVap; } - if ((CrossMixing(MixNum).FromZone == ZoneLoop) && state.dataZoneEquip->CrossMixingReportFlag(MixNum)) { - AirDensity = PsyRhoAirFnPbTdbW( - state, - state.dataEnvrn->OutBaroPress, - (state.dataHeatBalFanSys->MAT(ZoneLoop) + state.dataHeatBalFanSys->MAT(CrossMixing(MixNum).ZonePtr)) / 2.0, - (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) + state.dataHeatBalFanSys->ZoneAirHumRat(CrossMixing(MixNum).ZonePtr)) / 2.0, - std::string()); - CpAir = PsyCpAirFnW( - (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) + state.dataHeatBalFanSys->ZoneAirHumRat(CrossMixing(MixNum).ZonePtr)) / 2.0); + if ((CrossMixing(MixNum).FromZone == ZoneLoop) && CrossMixing(MixNum).ReportFlag) { + auto &mixingZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(CrossMixing(MixNum).ZonePtr); + AirDensity = PsyRhoAirFnPbTdbW(state, + state.dataEnvrn->OutBaroPress, + (thisZoneHB.MAT + mixingZoneHB.MAT) / 2.0, + (thisZoneHB.ZoneAirHumRat + mixingZoneHB.ZoneAirHumRat) / 2.0, + std::string()); + CpAir = PsyCpAirFnW((thisZoneHB.ZoneAirHumRat + mixingZoneHB.ZoneAirHumRat) / 2.0); ZnAirRpt(ZoneLoop).MixVolume += CrossMixing(MixNum).DesiredAirFlowRate * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).MixVdotCurDensity += CrossMixing(MixNum).DesiredAirFlowRate * ADSCorrectionFactor; @@ -2719,15 +2723,10 @@ void ReportAirHeatBalance(EnergyPlusData &state) ZnAirRpt(ZoneLoop).MixMdot += CrossMixing(MixNum).DesiredAirFlowRate * AirDensity * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).MixVdotStdDensity += CrossMixing(MixNum).DesiredAirFlowRate * (AirDensity / state.dataEnvrn->StdRhoAir) * ADSCorrectionFactor; - MixSenLoad(ZoneLoop) += CrossMixing(MixNum).DesiredAirFlowRate * AirDensity * CpAir * - (state.dataHeatBalFanSys->MAT(ZoneLoop) - state.dataHeatBalFanSys->MAT(CrossMixing(MixNum).ZonePtr)); - H2OHtOfVap = PsyHgAirFnWTdb( - (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) + state.dataHeatBalFanSys->ZoneAirHumRat(CrossMixing(MixNum).ZonePtr)) / 2.0, - (state.dataHeatBalFanSys->MAT(ZoneLoop) + state.dataHeatBalFanSys->MAT(CrossMixing(MixNum).ZonePtr)) / 2.0); + MixSenLoad(ZoneLoop) += CrossMixing(MixNum).DesiredAirFlowRate * AirDensity * CpAir * (thisZoneHB.MAT - mixingZoneHB.MAT); + H2OHtOfVap = PsyHgAirFnWTdb((thisZoneHB.ZoneAirHumRat + mixingZoneHB.ZoneAirHumRat) / 2.0, (thisZoneHB.MAT + mixingZoneHB.MAT) / 2.0); MixLatLoad(ZoneLoop) += - CrossMixing(MixNum).DesiredAirFlowRate * AirDensity * - (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) - state.dataHeatBalFanSys->ZoneAirHumRat(CrossMixing(MixNum).ZonePtr)) * - H2OHtOfVap; + CrossMixing(MixNum).DesiredAirFlowRate * AirDensity * (thisZoneHB.ZoneAirHumRat - mixingZoneHB.ZoneAirHumRat) * H2OHtOfVap; } } @@ -2738,22 +2737,20 @@ void ReportAirHeatBalance(EnergyPlusData &state) // in input with lowest zone # first no matter how input in idf if (RefDoorMixing(ZoneLoop).RefDoorMixFlag) { // .TRUE. for both zoneA and zoneB if (RefDoorMixing(ZoneLoop).ZonePtr == ZoneLoop) { - for (j = 1; j <= RefDoorMixing(ZoneLoop).NumRefDoorConnections; ++j) { + for (int j = 1; j <= RefDoorMixing(ZoneLoop).NumRefDoorConnections; ++j) { // Capture impact when zoneloop is the 'primary zone' // that is, the zone of a pair with the lower zone number if (RefDoorMixing(ZoneLoop).VolRefDoorFlowRate(j) > 0.0) { - ZoneB = RefDoorMixing(ZoneLoop).MateZonePtr(j); - AirDensity = PsyRhoAirFnPbTdbW( - state, - state.dataEnvrn->OutBaroPress, - (state.dataHeatBalFanSys->MAT(ZoneLoop) + state.dataHeatBalFanSys->MAT(ZoneB)) / 2.0, - (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) + state.dataHeatBalFanSys->ZoneAirHumRat(ZoneB)) / 2.0, - std::string()); - CpAir = - PsyCpAirFnW((state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) + state.dataHeatBalFanSys->ZoneAirHumRat(ZoneB)) / 2.0); - H2OHtOfVap = PsyHgAirFnWTdb( - (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) + state.dataHeatBalFanSys->ZoneAirHumRat(ZoneB)) / 2.0, - (state.dataHeatBalFanSys->MAT(ZoneLoop) + state.dataHeatBalFanSys->MAT(ZoneB)) / 2.0); + int ZoneB = RefDoorMixing(ZoneLoop).MateZonePtr(j); + auto &zoneBHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneB); + AirDensity = PsyRhoAirFnPbTdbW(state, + state.dataEnvrn->OutBaroPress, + (thisZoneHB.MAT + zoneBHB.MAT) / 2.0, + (thisZoneHB.ZoneAirHumRat + zoneBHB.ZoneAirHumRat) / 2.0, + std::string()); + CpAir = PsyCpAirFnW((thisZoneHB.ZoneAirHumRat + zoneBHB.ZoneAirHumRat) / 2.0); + H2OHtOfVap = + PsyHgAirFnWTdb((thisZoneHB.ZoneAirHumRat + zoneBHB.ZoneAirHumRat) / 2.0, (thisZoneHB.MAT + zoneBHB.MAT) / 2.0); ZnAirRpt(ZoneLoop).MixVolume += RefDoorMixing(ZoneLoop).VolRefDoorFlowRate(j) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).MixVdotCurDensity += RefDoorMixing(ZoneLoop).VolRefDoorFlowRate(j) * ADSCorrectionFactor; @@ -2762,32 +2759,29 @@ void ReportAirHeatBalance(EnergyPlusData &state) ZnAirRpt(ZoneLoop).MixMdot += RefDoorMixing(ZoneLoop).VolRefDoorFlowRate(j) * AirDensity * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).MixVdotStdDensity += RefDoorMixing(ZoneLoop).VolRefDoorFlowRate(j) * (AirDensity / state.dataEnvrn->StdRhoAir) * ADSCorrectionFactor; - MixSenLoad(ZoneLoop) += RefDoorMixing(ZoneLoop).VolRefDoorFlowRate(j) * AirDensity * CpAir * - (state.dataHeatBalFanSys->MAT(ZoneLoop) - state.dataHeatBalFanSys->MAT(ZoneB)); - MixLatLoad(ZoneLoop) += - RefDoorMixing(ZoneLoop).VolRefDoorFlowRate(j) * AirDensity * - (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) - state.dataHeatBalFanSys->ZoneAirHumRat(ZoneB)) * H2OHtOfVap; + MixSenLoad(ZoneLoop) += + RefDoorMixing(ZoneLoop).VolRefDoorFlowRate(j) * AirDensity * CpAir * (thisZoneHB.MAT - zoneBHB.MAT); + MixLatLoad(ZoneLoop) += RefDoorMixing(ZoneLoop).VolRefDoorFlowRate(j) * AirDensity * + (thisZoneHB.ZoneAirHumRat - zoneBHB.ZoneAirHumRat) * H2OHtOfVap; } // flow > 0 } // J-1, numref connections } // zone A (zoneptr = zoneloop) - for (ZoneA = 1; ZoneA <= (ZoneLoop - 1); ++ZoneA) { + for (int ZoneA = 1; ZoneA <= (ZoneLoop - 1); ++ZoneA) { + auto &zoneAHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneA); // Capture impact when zoneloop is the 'mating zone' // that is, the zone of a pair with the higher zone number(matezoneptr = zoneloop) if (RefDoorMixing(ZoneA).RefDoorMixFlag) { - for (j = 1; j <= RefDoorMixing(ZoneA).NumRefDoorConnections; ++j) { + for (int j = 1; j <= RefDoorMixing(ZoneA).NumRefDoorConnections; ++j) { if (RefDoorMixing(ZoneA).MateZonePtr(j) == ZoneLoop) { if (RefDoorMixing(ZoneA).VolRefDoorFlowRate(j) > 0.0) { - AirDensity = PsyRhoAirFnPbTdbW( - state, - state.dataEnvrn->OutBaroPress, - (state.dataHeatBalFanSys->MAT(ZoneLoop) + state.dataHeatBalFanSys->MAT(ZoneA)) / 2.0, - (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) + state.dataHeatBalFanSys->ZoneAirHumRat(ZoneA)) / 2.0, - std::string()); - CpAir = PsyCpAirFnW( - (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) + state.dataHeatBalFanSys->ZoneAirHumRat(ZoneA)) / 2.0); - H2OHtOfVap = PsyHgAirFnWTdb( - (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) + state.dataHeatBalFanSys->ZoneAirHumRat(ZoneA)) / 2.0, - (state.dataHeatBalFanSys->MAT(ZoneLoop) + state.dataHeatBalFanSys->MAT(ZoneA)) / 2.0); + AirDensity = PsyRhoAirFnPbTdbW(state, + state.dataEnvrn->OutBaroPress, + (thisZoneHB.MAT + zoneAHB.MAT) / 2.0, + (thisZoneHB.ZoneAirHumRat + zoneAHB.ZoneAirHumRat) / 2.0, + std::string()); + CpAir = PsyCpAirFnW((thisZoneHB.ZoneAirHumRat + zoneAHB.ZoneAirHumRat) / 2.0); + H2OHtOfVap = PsyHgAirFnWTdb((thisZoneHB.ZoneAirHumRat + zoneAHB.ZoneAirHumRat) / 2.0, + (thisZoneHB.MAT + zoneAHB.MAT) / 2.0); ZnAirRpt(ZoneLoop).MixVolume += RefDoorMixing(ZoneA).VolRefDoorFlowRate(j) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).MixVdotCurDensity += RefDoorMixing(ZoneA).VolRefDoorFlowRate(j) * ADSCorrectionFactor; @@ -2796,12 +2790,10 @@ void ReportAirHeatBalance(EnergyPlusData &state) ZnAirRpt(ZoneLoop).MixMdot += RefDoorMixing(ZoneA).VolRefDoorFlowRate(j) * AirDensity * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).MixVdotStdDensity += RefDoorMixing(ZoneA).VolRefDoorFlowRate(j) * (AirDensity / state.dataEnvrn->StdRhoAir) * ADSCorrectionFactor; - MixSenLoad(ZoneLoop) += RefDoorMixing(ZoneA).VolRefDoorFlowRate(j) * AirDensity * CpAir * - (state.dataHeatBalFanSys->MAT(ZoneLoop) - state.dataHeatBalFanSys->MAT(ZoneA)); - MixLatLoad(ZoneLoop) += - RefDoorMixing(ZoneA).VolRefDoorFlowRate(j) * AirDensity * - (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) - state.dataHeatBalFanSys->ZoneAirHumRat(ZoneA)) * - H2OHtOfVap; + MixSenLoad(ZoneLoop) += + RefDoorMixing(ZoneA).VolRefDoorFlowRate(j) * AirDensity * CpAir * (thisZoneHB.MAT - zoneAHB.MAT); + MixLatLoad(ZoneLoop) += RefDoorMixing(ZoneA).VolRefDoorFlowRate(j) * AirDensity * + (thisZoneHB.ZoneAirHumRat - zoneAHB.ZoneAirHumRat) * H2OHtOfVap; } // volflowrate > 0 } // matezoneptr (zoneB) = Zonelooop } // NumRefDoorConnections @@ -2840,29 +2832,25 @@ void ReportAirHeatBalance(EnergyPlusData &state) } // Reporting combined outdoor air flows - for (j = 1; j <= state.dataHeatBal->TotZoneAirBalance; ++j) { + for (int j = 1; j <= state.dataHeatBal->TotZoneAirBalance; ++j) { if (state.dataHeatBal->ZoneAirBalance(j).BalanceMethod == DataHeatBalance::AirBalance::Quadrature && ZoneLoop == state.dataHeatBal->ZoneAirBalance(j).ZonePtr) { - if (state.dataHeatBalFanSys->MAT(ZoneLoop) > Zone(ZoneLoop).OutDryBulbTemp) { - ZnAirRpt(ZoneLoop).OABalanceHeatLoss = state.dataHeatBalFanSys->MDotCPOA(ZoneLoop) * - (state.dataHeatBalFanSys->MAT(ZoneLoop) - Zone(ZoneLoop).OutDryBulbTemp) * TimeStepSys * + if (thisZoneHB.MAT > Zone(ZoneLoop).OutDryBulbTemp) { + ZnAirRpt(ZoneLoop).OABalanceHeatLoss = thisZoneHB.MDotCPOA * (thisZoneHB.MAT - Zone(ZoneLoop).OutDryBulbTemp) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).OABalanceHeatGain = 0.0; } else { ZnAirRpt(ZoneLoop).OABalanceHeatLoss = 0.0; - ZnAirRpt(ZoneLoop).OABalanceHeatGain = -state.dataHeatBalFanSys->MDotCPOA(ZoneLoop) * - (state.dataHeatBalFanSys->MAT(ZoneLoop) - Zone(ZoneLoop).OutDryBulbTemp) * TimeStepSys * + ZnAirRpt(ZoneLoop).OABalanceHeatGain = -thisZoneHB.MDotCPOA * (thisZoneHB.MAT - Zone(ZoneLoop).OutDryBulbTemp) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; } H2OHtOfVap = PsyHgAirFnWTdb(state.dataEnvrn->OutHumRat, Zone(ZoneLoop).OutDryBulbTemp); - if (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) > state.dataEnvrn->OutHumRat) { - ZnAirRpt(ZoneLoop).OABalanceLatentLoss = state.dataHeatBalFanSys->MDotOA(ZoneLoop) * - (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) - state.dataEnvrn->OutHumRat) * + if (thisZoneHB.ZoneAirHumRat > state.dataEnvrn->OutHumRat) { + ZnAirRpt(ZoneLoop).OABalanceLatentLoss = thisZoneHB.MDotOA * (thisZoneHB.ZoneAirHumRat - state.dataEnvrn->OutHumRat) * H2OHtOfVap * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).OABalanceLatentGain = 0.0; - } else if (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) <= state.dataEnvrn->OutHumRat) { - ZnAirRpt(ZoneLoop).OABalanceLatentGain = state.dataHeatBalFanSys->MDotOA(ZoneLoop) * - (state.dataEnvrn->OutHumRat - state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop)) * + } else if (thisZoneHB.ZoneAirHumRat <= state.dataEnvrn->OutHumRat) { + ZnAirRpt(ZoneLoop).OABalanceLatentGain = thisZoneHB.MDotOA * (state.dataEnvrn->OutHumRat - thisZoneHB.ZoneAirHumRat) * H2OHtOfVap * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).OABalanceLatentLoss = 0.0; } @@ -2876,22 +2864,17 @@ void ReportAirHeatBalance(EnergyPlusData &state) ZnAirRpt(ZoneLoop).OABalanceTotalGain = 0.0; ZnAirRpt(ZoneLoop).OABalanceTotalLoss = -TotalLoad * ADSCorrectionFactor; } - ZnAirRpt(ZoneLoop).OABalanceMass = - (state.dataHeatBalFanSys->MDotOA(ZoneLoop)) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; - ZnAirRpt(ZoneLoop).OABalanceMdot = (state.dataHeatBalFanSys->MDotOA(ZoneLoop)) * ADSCorrectionFactor; - AirDensity = PsyRhoAirFnPbTdbW(state, - state.dataEnvrn->OutBaroPress, - state.dataHeatBalFanSys->MAT(ZoneLoop), - state.dataHeatBalFanSys->ZoneAirHumRatAvg(ZoneLoop), - std::string()); + ZnAirRpt(ZoneLoop).OABalanceMass = (thisZoneHB.MDotOA) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; + ZnAirRpt(ZoneLoop).OABalanceMdot = (thisZoneHB.MDotOA) * ADSCorrectionFactor; + AirDensity = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, thisZoneHB.MAT, thisZoneHB.ZoneAirHumRatAvg, std::string()); ZnAirRpt(ZoneLoop).OABalanceVolumeCurDensity = - (state.dataHeatBalFanSys->MDotOA(ZoneLoop) / AirDensity) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; + (thisZoneHB.MDotOA / AirDensity) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).OABalanceAirChangeRate = ZnAirRpt(ZoneLoop).OABalanceVolumeCurDensity / (TimeStepSys * Zone(ZoneLoop).Volume); - ZnAirRpt(ZoneLoop).OABalanceVdotCurDensity = (state.dataHeatBalFanSys->MDotOA(ZoneLoop) / AirDensity) * ADSCorrectionFactor; + ZnAirRpt(ZoneLoop).OABalanceVdotCurDensity = (thisZoneHB.MDotOA / AirDensity) * ADSCorrectionFactor; AirDensity = state.dataEnvrn->StdRhoAir; ZnAirRpt(ZoneLoop).OABalanceVolumeStdDensity = - (state.dataHeatBalFanSys->MDotOA(ZoneLoop) / AirDensity) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; - ZnAirRpt(ZoneLoop).OABalanceVdotStdDensity = (state.dataHeatBalFanSys->MDotOA(ZoneLoop) / AirDensity) * ADSCorrectionFactor; + (thisZoneHB.MDotOA / AirDensity) * TimeStepSys * DataGlobalConstants::SecInHour * ADSCorrectionFactor; + ZnAirRpt(ZoneLoop).OABalanceVdotStdDensity = (thisZoneHB.MDotOA / AirDensity) * ADSCorrectionFactor; ZnAirRpt(ZoneLoop).OABalanceFanElec = ZnAirRpt(ZoneLoop).VentilFanElec; } } @@ -2917,9 +2900,9 @@ void ReportAirHeatBalance(EnergyPlusData &state) ZnAirRpt(ZoneLoop).ExfilMass = ZnAirRpt(ZoneLoop).InfilMass + ZnAirRpt(ZoneLoop).VentilMass + ZnAirRpt(ZoneLoop).MixMass + ZnAirRpt(ZoneLoop).OABalanceMass + ZnAirRpt(ZoneLoop).SysInletMass - ZnAirRpt(ZoneLoop).SysOutletMass; // kg ZnAirRpt(ZoneLoop).ExfilSensiLoss = ZnAirRpt(ZoneLoop).ExfilMass / (TimeStepSys * DataGlobalConstants::SecInHour) * - (state.dataHeatBalFanSys->MAT(ZoneLoop) - Zone(ZoneLoop).OutDryBulbTemp) * CpAir; // W + (thisZoneHB.MAT - Zone(ZoneLoop).OutDryBulbTemp) * CpAir; // W ZnAirRpt(ZoneLoop).ExfilLatentLoss = ZnAirRpt(ZoneLoop).ExfilMass / (TimeStepSys * DataGlobalConstants::SecInHour) * - (state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop) - state.dataEnvrn->OutHumRat) * H2OHtOfVap; + (thisZoneHB.ZoneAirHumRat - state.dataEnvrn->OutHumRat) * H2OHtOfVap; ZnAirRpt(ZoneLoop).ExfilTotalLoss = ZnAirRpt(ZoneLoop).ExfilLatentLoss + ZnAirRpt(ZoneLoop).ExfilSensiLoss; state.dataHeatBal->ZoneTotalExfiltrationHeatLoss += ZnAirRpt(ZoneLoop).ExfilTotalLoss * TimeStepSys * DataGlobalConstants::SecInHour; @@ -2953,7 +2936,6 @@ void SetHeatToReturnAirFlag(EnergyPlusData &state) bool CyclingFan(false); // TRUE means air loop operates in cycling fan mode at some point - auto &Zone(state.dataHeatBal->Zone); auto &AirLoopControlInfo(state.dataAirLoop->AirLoopControlInfo); auto &ZoneEquipConfig(state.dataZoneEquip->ZoneEquipConfig); @@ -3003,27 +2985,28 @@ void SetHeatToReturnAirFlag(EnergyPlusData &state) } } if (ZoneEquipConfig(ControlledZoneNum).ZonalSystemOnly || CyclingFan) { - if (Zone(ControlledZoneNum).RefrigCaseRA) { + auto const &thisZone = state.dataHeatBal->Zone(ControlledZoneNum); + if (thisZone.RefrigCaseRA) { ShowWarningError(state, - "For zone=" + Zone(ControlledZoneNum).Name + - " return air cooling by refrigerated cases will be applied to the zone air."); + "For zone=" + thisZone.Name + " return air cooling by refrigerated cases will be applied to the zone air."); ShowContinueError(state, " This zone has no return air or is served by an on/off HVAC system."); } for (int LightNum = 1; LightNum <= state.dataHeatBal->TotLights; ++LightNum) { if (state.dataHeatBal->Lights(LightNum).ZonePtr != ControlledZoneNum) continue; if (state.dataHeatBal->Lights(LightNum).FractionReturnAir > 0.0) { - ShowWarningError( - state, "For zone=" + Zone(ControlledZoneNum).Name + " return air heat gain from lights will be applied to the zone air."); + ShowWarningError(state, "For zone=" + thisZone.Name + " return air heat gain from lights will be applied to the zone air."); ShowContinueError(state, " This zone has no return air or is served by an on/off HVAC system."); break; } } - for (int SurfNum = Zone(ControlledZoneNum).HTSurfaceFirst; SurfNum <= Zone(ControlledZoneNum).HTSurfaceLast; ++SurfNum) { - if (state.dataSurface->SurfWinAirflowDestination(SurfNum) == DataSurfaces::WindowAirFlowDestination::Return) { - ShowWarningError(state, - "For zone=" + Zone(ControlledZoneNum).Name + - " return air heat gain from air flow windows will be applied to the zone air."); - ShowContinueError(state, " This zone has no return air or is served by an on/off HVAC system."); + for (int spaceNum : thisZone.spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { + if (state.dataSurface->SurfWinAirflowDestination(SurfNum) == DataSurfaces::WindowAirFlowDestination::Return) { + ShowWarningError( + state, "For zone=" + thisZone.Name + " return air heat gain from air flow windows will be applied to the zone air."); + ShowContinueError(state, " This zone has no return air or is served by an on/off HVAC system."); + } } } } @@ -3044,14 +3027,15 @@ void SetHeatToReturnAirFlag(EnergyPlusData &state) // set the zone level NoHeatToReturnAir flag // if any air loop in the zone is continuous fan, then set NoHeatToReturnAir = false and sort it out node-by-node for (int ControlledZoneNum = 1; ControlledZoneNum <= state.dataGlobal->NumOfZones; ++ControlledZoneNum) { + auto &thisZone = state.dataHeatBal->Zone(ControlledZoneNum); if (!ZoneEquipConfig(ControlledZoneNum).IsControlled) continue; - Zone(ControlledZoneNum).NoHeatToReturnAir = true; + thisZone.NoHeatToReturnAir = true; if (!ZoneEquipConfig(ControlledZoneNum).ZonalSystemOnly) { for (int zoneInNode = 1; zoneInNode <= ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++zoneInNode) { int AirLoopNum = ZoneEquipConfig(ControlledZoneNum).InletNodeAirLoopNum(zoneInNode); if (AirLoopNum > 0) { if (AirLoopControlInfo(AirLoopNum).FanOpMode == ContFanCycCoil) { - Zone(ControlledZoneNum).NoHeatToReturnAir = false; + thisZone.NoHeatToReturnAir = false; break; } } diff --git a/src/EnergyPlus/HVACMultiSpeedHeatPump.cc b/src/EnergyPlus/HVACMultiSpeedHeatPump.cc index 04ccc72af36..fc325e77c00 100644 --- a/src/EnergyPlus/HVACMultiSpeedHeatPump.cc +++ b/src/EnergyPlus/HVACMultiSpeedHeatPump.cc @@ -61,7 +61,6 @@ #include #include #include -#include #include #include #include @@ -3793,13 +3792,17 @@ namespace HVACMultiSpeedHeatPump { InletNode = MSHeatPump(MSHeatPumpNum).AirInletNodeNum; if (MSHeatPump(MSHeatPumpNum).DXHeatCoilIndex > 0) { if (state.dataDXCoils->DXCoil(MSHeatPump(MSHeatPumpNum).DXHeatCoilIndex).IsSecondaryDXCoilInZone) { - OutsideDryBulbTemp = state.dataHeatBalFanSys->ZT(state.dataDXCoils->DXCoil(MSHeatPump(MSHeatPumpNum).DXHeatCoilIndex).SecZonePtr); + OutsideDryBulbTemp = state.dataZoneTempPredictorCorrector + ->zoneHeatBalance(state.dataDXCoils->DXCoil(MSHeatPump(MSHeatPumpNum).DXHeatCoilIndex).SecZonePtr) + .ZT; } else { OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp; } } else if (MSHeatPump(MSHeatPumpNum).DXCoolCoilIndex > 0) { if (state.dataDXCoils->DXCoil(MSHeatPump(MSHeatPumpNum).DXCoolCoilIndex).IsSecondaryDXCoilInZone) { - OutsideDryBulbTemp = state.dataHeatBalFanSys->ZT(state.dataDXCoils->DXCoil(MSHeatPump(MSHeatPumpNum).DXCoolCoilIndex).SecZonePtr); + OutsideDryBulbTemp = state.dataZoneTempPredictorCorrector + ->zoneHeatBalance(state.dataDXCoils->DXCoil(MSHeatPump(MSHeatPumpNum).DXCoolCoilIndex).SecZonePtr) + .ZT; } else { OutsideDryBulbTemp = state.dataEnvrn->OutDryBulbTemp; } diff --git a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc index 23b7d6544f4..f07f0333ef5 100644 --- a/src/EnergyPlus/HVACVariableRefrigerantFlow.cc +++ b/src/EnergyPlus/HVACVariableRefrigerantFlow.cc @@ -101,6 +101,7 @@ #include #include #include +#include namespace EnergyPlus::HVACVariableRefrigerantFlow { // Module containing the Variable Refrigerant Flow (VRF or VRV) simulation routines @@ -10349,6 +10350,7 @@ void InitializeOperatingMode(EnergyPlusData &state, if (state.dataHVACVarRefFlow->VRF(VRFCond).ThermostatPriority == ThermostatCtrlType::ThermostatOffsetPriority) { // for TSTATPriority, just check difference between zone temp and thermostat setpoint if (ThisZoneNum > 0) { + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ThisZoneNum); SPTempHi = state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ThisZoneNum); SPTempLo = state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ThisZoneNum); @@ -10358,16 +10360,16 @@ void InitializeOperatingMode(EnergyPlusData &state, break; case DataHVACGlobals::ThermostatType::SingleHeating: // if heating load, ZoneDeltaT will be negative - ZoneDeltaT = min(0.0, state.dataHeatBalFanSys->ZT(ThisZoneNum) - SPTempLo); + ZoneDeltaT = min(0.0, thisZoneHB.ZT - SPTempLo); state.dataHVACVarRefFlow->MinDeltaT(VRFCond) = min(state.dataHVACVarRefFlow->MinDeltaT(VRFCond), ZoneDeltaT); break; case DataHVACGlobals::ThermostatType::SingleCooling: // if cooling load, ZoneDeltaT will be positive - ZoneDeltaT = max(0.0, state.dataHeatBalFanSys->ZT(ThisZoneNum) - SPTempHi); + ZoneDeltaT = max(0.0, thisZoneHB.ZT - SPTempHi); state.dataHVACVarRefFlow->MaxDeltaT(VRFCond) = max(state.dataHVACVarRefFlow->MaxDeltaT(VRFCond), ZoneDeltaT); break; case DataHVACGlobals::ThermostatType::SingleHeatCool: - ZoneDeltaT = state.dataHeatBalFanSys->ZT(ThisZoneNum) - SPTempHi; //- SPTempHi and SPTempLo are same value + ZoneDeltaT = thisZoneHB.ZT - SPTempHi; //- SPTempHi and SPTempLo are same value if (ZoneDeltaT > 0.0) { state.dataHVACVarRefFlow->MaxDeltaT(VRFCond) = max(state.dataHVACVarRefFlow->MaxDeltaT(VRFCond), ZoneDeltaT); } else { @@ -10375,11 +10377,11 @@ void InitializeOperatingMode(EnergyPlusData &state, } break; case DataHVACGlobals::ThermostatType::DualSetPointWithDeadBand: - if (state.dataHeatBalFanSys->ZT(ThisZoneNum) - SPTempHi > 0.0) { - ZoneDeltaT = max(0.0, state.dataHeatBalFanSys->ZT(ThisZoneNum) - SPTempHi); + if (thisZoneHB.ZT - SPTempHi > 0.0) { + ZoneDeltaT = max(0.0, thisZoneHB.ZT - SPTempHi); state.dataHVACVarRefFlow->MaxDeltaT(VRFCond) = max(state.dataHVACVarRefFlow->MaxDeltaT(VRFCond), ZoneDeltaT); - } else if (SPTempLo - state.dataHeatBalFanSys->ZT(ThisZoneNum) > 0.0) { - ZoneDeltaT = min(0.0, state.dataHeatBalFanSys->ZT(ThisZoneNum) - SPTempLo); + } else if (SPTempLo - thisZoneHB.ZT > 0.0) { + ZoneDeltaT = min(0.0, thisZoneHB.ZT - SPTempLo); state.dataHVACVarRefFlow->MinDeltaT(VRFCond) = min(state.dataHVACVarRefFlow->MinDeltaT(VRFCond), ZoneDeltaT); } break; diff --git a/src/EnergyPlus/HWBaseboardRadiator.cc b/src/EnergyPlus/HWBaseboardRadiator.cc index ee40b67b83d..999da3039b0 100644 --- a/src/EnergyPlus/HWBaseboardRadiator.cc +++ b/src/EnergyPlus/HWBaseboardRadiator.cc @@ -963,7 +963,7 @@ namespace HWBaseboardRadiator { if (state.dataGlobal->BeginTimeStepFlag && FirstHVACIteration) { int ZoneNum = HWBaseboard(BaseboardNum).ZonePtr; - ZeroSourceSumHATsurf(ZoneNum) = SumHATsurf(state, ZoneNum); + ZeroSourceSumHATsurf(ZoneNum) = state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state); QBBRadSrcAvg(BaseboardNum) = 0.0; LastQBBRadSrc(BaseboardNum) = 0.0; LastSysTimeElapsed(BaseboardNum) = 0.0; @@ -1464,8 +1464,8 @@ namespace HWBaseboardRadiator { // that all energy radiated to people is converted to convective energy is // not very precise, but at least it conserves energy. The system impact to heat balance // should include this. - LoadMet = (SumHATsurf(state, ZoneNum) - ZeroSourceSumHATsurf(ZoneNum)) + (BBHeat * HWBaseboard(BaseboardNum).FracConvect) + - (RadHeat * HWBaseboardDesignDataObject.FracDistribPerson); + LoadMet = (state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state) - ZeroSourceSumHATsurf(ZoneNum)) + + (BBHeat * HWBaseboard(BaseboardNum).FracConvect) + (RadHeat * HWBaseboardDesignDataObject.FracDistribPerson); } HWBaseboard(BaseboardNum).WaterOutletEnthalpy = HWBaseboard(BaseboardNum).WaterInletEnthalpy - BBHeat / WaterMassFlowRate; } else { @@ -1730,71 +1730,6 @@ namespace HWBaseboardRadiator { HWBaseboard(BaseboardNum).RadEnergy = HWBaseboard(BaseboardNum).RadPower * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour; } - Real64 SumHATsurf(EnergyPlusData &state, int const ZoneNum) // Zone number - { - - // FUNCTION INFORMATION: - // AUTHOR Peter Graham Ellis - // DATE WRITTEN July 2003 - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS FUNCTION: - // This function calculates the zone sum of Hc*Area*Tsurf. It replaces the old SUMHAT. - // The SumHATsurf code below is also in the CalcZoneSums subroutine in ZoneTempPredictorCorrector - // and should be updated accordingly. - - // METHODOLOGY EMPLOYED: - // na - - // REFERENCES: - // na - - // Using/Aliasing - using namespace DataSurfaces; - using namespace DataHeatBalance; - - // Return value - Real64 SumHATsurf; - - // Locals - // FUNCTION ARGUMENT DEFINITIONS: - - // FUNCTION LOCAL VARIABLE DECLARATIONS: - int SurfNum; // Surface number - Real64 Area; // Effective surface area - - SumHATsurf = 0.0; - - for (SurfNum = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst; SurfNum <= state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast; ++SurfNum) { - Area = state.dataSurface->Surface(SurfNum).Area; - - if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Window) { - if (ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum))) { - // The area is the shade or blind area = the sum of the glazing area and the divider area (which is zero if no divider) - Area += state.dataSurface->SurfWinDividerArea(SurfNum); - } - - if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) { - // Window frame contribution - SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinFrameArea(SurfNum) * - (1.0 + state.dataSurface->SurfWinProjCorrFrIn(SurfNum)) * state.dataSurface->SurfWinFrameTempIn(SurfNum); - } - - if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0 && - !ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum))) { - // Window divider contribution (only from shade or blind for window with divider and interior shade or blind) - SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinDividerArea(SurfNum) * - (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) * state.dataSurface->SurfWinDividerTempIn(SurfNum); - } - } - - SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * Area * state.dataHeatBalSurf->SurfTempInTmp(SurfNum); - } - - return SumHATsurf; - } - void UpdateHWBaseboardPlantConnection(EnergyPlusData &state, int const BaseboardTypeNum, // type index std::string const &BaseboardName, // component name diff --git a/src/EnergyPlus/HWBaseboardRadiator.hh b/src/EnergyPlus/HWBaseboardRadiator.hh index fd1dc5a0725..fe9cb9a05a5 100644 --- a/src/EnergyPlus/HWBaseboardRadiator.hh +++ b/src/EnergyPlus/HWBaseboardRadiator.hh @@ -198,8 +198,6 @@ namespace HWBaseboardRadiator { void ReportHWBaseboard(EnergyPlusData &state, int const BaseboardNum); - Real64 SumHATsurf(EnergyPlusData &state, int const ZoneNum); // Zone number - void UpdateHWBaseboardPlantConnection(EnergyPlusData &state, int const BaseboardTypeNum, // type index std::string const &BaseboardName, // component name diff --git a/src/EnergyPlus/HeatBalFiniteDiffManager.cc b/src/EnergyPlus/HeatBalFiniteDiffManager.cc index 3908dfa1bb2..9e2e5315b4a 100644 --- a/src/EnergyPlus/HeatBalFiniteDiffManager.cc +++ b/src/EnergyPlus/HeatBalFiniteDiffManager.cc @@ -74,6 +74,7 @@ #include #include #include +#include namespace EnergyPlus { @@ -2298,7 +2299,7 @@ namespace HeatBalFiniteDiffManager { // Boundary Conditions from Simulation for Interior Real64 hconvi(state.dataMstBal->HConvInFD(Surf)); - Real64 const Tia(state.dataHeatBalFanSys->MAT(surface.Zone)); + Real64 const Tia(state.dataZoneTempPredictorCorrector->zoneHeatBalance(surface.Zone).MAT); //++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Do all the nodes in the surface Else will switch to SigmaR,SigmaC diff --git a/src/EnergyPlus/HeatBalanceAirManager.cc b/src/EnergyPlus/HeatBalanceAirManager.cc index d67c27b50c4..e3212e256e5 100644 --- a/src/EnergyPlus/HeatBalanceAirManager.cc +++ b/src/EnergyPlus/HeatBalanceAirManager.cc @@ -61,6 +61,7 @@ #include #include #include +#include #include #include #include @@ -103,7 +104,6 @@ namespace EnergyPlus::HeatBalanceAirManager { // USE STATEMENTS: using namespace DataEnvironment; -using namespace DataHeatBalFanSys; using namespace DataHeatBalance; using namespace DataSurfaces; @@ -339,152 +339,81 @@ void GetSimpleAirModelInputs(EnergyPlusData &state, bool &ErrorsFound) // IF err // Following used for reporting state.dataHeatBal->ZnAirRpt.allocate(state.dataGlobal->NumOfZones); + if (state.dataHeatBal->doSpaceHeatBalanceSizing || state.dataHeatBal->doSpaceHeatBalanceSimulation) { + state.dataHeatBal->spaceAirRpt.allocate(state.dataGlobal->NumOfZones); + } for (int Loop = 1; Loop <= state.dataGlobal->NumOfZones; ++Loop) { + std::string_view name = state.dataHeatBal->Zone(Loop).Name; + auto &thisZnAirRpt = state.dataHeatBal->ZnAirRpt(Loop); + thisZnAirRpt.setUpOutputVars(state, DataStringGlobals::zonePrefix, name); + if (state.dataHeatBal->doSpaceHeatBalanceSizing || state.dataHeatBal->doSpaceHeatBalanceSimulation) { + for (int spaceNum : state.dataHeatBal->Zone(Loop).spaceIndexes) { + state.dataHeatBal->spaceAirRpt(spaceNum).setUpOutputVars( + state, DataStringGlobals::spacePrefix, state.dataHeatBal->space(spaceNum).Name); + } + } + // CurrentModuleObject='Zone' - SetupOutputVariable(state, - "Zone Mean Air Temperature", - OutputProcessor::Unit::C, - state.dataHeatBal->ZnAirRpt(Loop).MeanAirTemp, - OutputProcessor::SOVTimeStepType::Zone, - OutputProcessor::SOVStoreType::Average, - state.dataHeatBal->Zone(Loop).Name); - SetupOutputVariable(state, - "Zone Operative Temperature", - OutputProcessor::Unit::C, - state.dataHeatBal->ZnAirRpt(Loop).OperativeTemp, - OutputProcessor::SOVTimeStepType::Zone, - OutputProcessor::SOVStoreType::Average, - state.dataHeatBal->Zone(Loop).Name); - SetupOutputVariable(state, - "Zone Mean Air Dewpoint Temperature", - OutputProcessor::Unit::C, - state.dataHeatBal->ZnAirRpt(Loop).MeanAirDewPointTemp, - OutputProcessor::SOVTimeStepType::Zone, - OutputProcessor::SOVStoreType::Average, - state.dataHeatBal->Zone(Loop).Name); - SetupOutputVariable(state, - "Zone Mean Air Humidity Ratio", - OutputProcessor::Unit::kgWater_kgDryAir, - state.dataHeatBal->ZnAirRpt(Loop).MeanAirHumRat, - OutputProcessor::SOVTimeStepType::Zone, - OutputProcessor::SOVStoreType::Average, - state.dataHeatBal->Zone(Loop).Name); - SetupOutputVariable(state, - "Zone Air Heat Balance Internal Convective Heat Gain Rate", - OutputProcessor::Unit::W, - state.dataHeatBal->ZnAirRpt(Loop).SumIntGains, - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - state.dataHeatBal->Zone(Loop).Name); - SetupOutputVariable(state, - "Zone Air Heat Balance Surface Convection Rate", - OutputProcessor::Unit::W, - state.dataHeatBal->ZnAirRpt(Loop).SumHADTsurfs, - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - state.dataHeatBal->Zone(Loop).Name); - SetupOutputVariable(state, - "Zone Air Heat Balance Interzone Air Transfer Rate", - OutputProcessor::Unit::W, - state.dataHeatBal->ZnAirRpt(Loop).SumMCpDTzones, - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - state.dataHeatBal->Zone(Loop).Name); - SetupOutputVariable(state, - "Zone Air Heat Balance Outdoor Air Transfer Rate", - OutputProcessor::Unit::W, - state.dataHeatBal->ZnAirRpt(Loop).SumMCpDtInfil, - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - state.dataHeatBal->Zone(Loop).Name); - SetupOutputVariable(state, - "Zone Air Heat Balance System Air Transfer Rate", - OutputProcessor::Unit::W, - state.dataHeatBal->ZnAirRpt(Loop).SumMCpDTsystem, - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - state.dataHeatBal->Zone(Loop).Name); - SetupOutputVariable(state, - "Zone Air Heat Balance System Convective Heat Gain Rate", - OutputProcessor::Unit::W, - state.dataHeatBal->ZnAirRpt(Loop).SumNonAirSystem, - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - state.dataHeatBal->Zone(Loop).Name); - SetupOutputVariable(state, - "Zone Air Heat Balance Air Energy Storage Rate", - OutputProcessor::Unit::W, - state.dataHeatBal->ZnAirRpt(Loop).CzdTdt, - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - state.dataHeatBal->Zone(Loop).Name); if (state.dataGlobal->DisplayAdvancedReportVariables) { SetupOutputVariable(state, "Zone Phase Change Material Melting Enthalpy", OutputProcessor::Unit::J_kg, - state.dataHeatBal->ZnAirRpt(Loop).SumEnthalpyM, + thisZnAirRpt.SumEnthalpyM, OutputProcessor::SOVTimeStepType::Zone, OutputProcessor::SOVStoreType::Average, - state.dataHeatBal->Zone(Loop).Name); + name); SetupOutputVariable(state, "Zone Phase Change Material Freezing Enthalpy", OutputProcessor::Unit::J_kg, - state.dataHeatBal->ZnAirRpt(Loop).SumEnthalpyH, + thisZnAirRpt.SumEnthalpyH, OutputProcessor::SOVTimeStepType::Zone, OutputProcessor::SOVStoreType::Average, - state.dataHeatBal->Zone(Loop).Name); - SetupOutputVariable(state, - "Zone Air Heat Balance Deviation Rate", - OutputProcessor::Unit::W, - state.dataHeatBal->ZnAirRpt(Loop).imBalance, - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - state.dataHeatBal->Zone(Loop).Name); + name); } SetupOutputVariable(state, "Zone Exfiltration Heat Transfer Rate", OutputProcessor::Unit::W, - state.dataHeatBal->ZnAirRpt(Loop).ExfilTotalLoss, + thisZnAirRpt.ExfilTotalLoss, OutputProcessor::SOVTimeStepType::System, OutputProcessor::SOVStoreType::Average, - state.dataHeatBal->Zone(Loop).Name); + name); SetupOutputVariable(state, "Zone Exfiltration Sensible Heat Transfer Rate", OutputProcessor::Unit::W, - state.dataHeatBal->ZnAirRpt(Loop).ExfilSensiLoss, + thisZnAirRpt.ExfilSensiLoss, OutputProcessor::SOVTimeStepType::System, OutputProcessor::SOVStoreType::Average, - state.dataHeatBal->Zone(Loop).Name); + name); SetupOutputVariable(state, "Zone Exfiltration Latent Heat Transfer Rate", OutputProcessor::Unit::W, - state.dataHeatBal->ZnAirRpt(Loop).ExfilLatentLoss, + thisZnAirRpt.ExfilLatentLoss, OutputProcessor::SOVTimeStepType::System, OutputProcessor::SOVStoreType::Average, - state.dataHeatBal->Zone(Loop).Name); + name); SetupOutputVariable(state, "Zone Exhaust Air Heat Transfer Rate", OutputProcessor::Unit::W, - state.dataHeatBal->ZnAirRpt(Loop).ExhTotalLoss, + thisZnAirRpt.ExhTotalLoss, OutputProcessor::SOVTimeStepType::System, OutputProcessor::SOVStoreType::Average, - state.dataHeatBal->Zone(Loop).Name); + name); SetupOutputVariable(state, "Zone Exhaust Air Sensible Heat Transfer Rate", OutputProcessor::Unit::W, - state.dataHeatBal->ZnAirRpt(Loop).ExhSensiLoss, + thisZnAirRpt.ExhSensiLoss, OutputProcessor::SOVTimeStepType::System, OutputProcessor::SOVStoreType::Average, - state.dataHeatBal->Zone(Loop).Name); + name); SetupOutputVariable(state, "Zone Exhaust Air Latent Heat Transfer Rate", OutputProcessor::Unit::W, - state.dataHeatBal->ZnAirRpt(Loop).ExhLatentLoss, + thisZnAirRpt.ExhLatentLoss, OutputProcessor::SOVTimeStepType::System, OutputProcessor::SOVStoreType::Average, - state.dataHeatBal->Zone(Loop).Name); + name); } SetupOutputVariable(state, @@ -3475,7 +3404,7 @@ void GetSimpleAirModelInputs(EnergyPlusData &state, bool &ErrorsFound) // IF err int space1 = thisAirBoundaryMixing.space1; int space2 = thisAirBoundaryMixing.space2; int zone1 = state.dataHeatBal->space(space1).zoneNum; - int zone2 = state.dataHeatBal->space(space1).zoneNum; + int zone2 = state.dataHeatBal->space(space2).zoneNum; auto &thisCrossMizing = state.dataHeatBal->CrossMixing(mixingNum); thisCrossMizing.Name = fmt::format("Air Boundary Mixing Zones {} and {}", zone1, zone2); thisCrossMizing.spaceIndex = space1; @@ -3486,7 +3415,7 @@ void GetSimpleAirModelInputs(EnergyPlusData &state, bool &ErrorsFound) // IF err thisCrossMizing.fromSpaceIndex = space2; } assert(mixingNum == state.dataHeatBal->TotCrossMixing); - for (int mixingRepNum = 1; mixingRepNum <= state.dataHeatBal->TotMixing; ++mixingRepNum) { + for (int mixingRepNum = 1; mixingRepNum <= state.dataHeatBal->TotCrossMixing; ++mixingRepNum) { int zoneNum = state.dataHeatBal->CrossMixing(mixingRepNum).ZonePtr; if (zoneNum > 0) { std::string const &zoneName = state.dataHeatBal->Zone(zoneNum).Name; @@ -4429,6 +4358,11 @@ void GetRoomAirModelParameters(EnergyPlusData &state, bool &errFlag) // True if ShowSevereError(state, "Too many " + cCurrentModuleObject + ". Cannot exceed the number of Zones."); ErrorsFound = true; } + if (NumOfAirModels > 0) { + state.dataRoomAirMod->IsZoneDV.dimension(state.dataGlobal->NumOfZones, false); + state.dataRoomAirMod->IsZoneCV.dimension(state.dataGlobal->NumOfZones, false); + state.dataRoomAirMod->IsZoneUI.dimension(state.dataGlobal->NumOfZones, false); + } for (AirModelNum = 1; AirModelNum <= NumOfAirModels; ++AirModelNum) { state.dataInputProcessing->inputProcessor->getObjectItem(state, @@ -4592,6 +4526,17 @@ void GetRoomAirModelParameters(EnergyPlusData &state, bool &errFlag) // True if // this used to be an if (NumOfAirModels == 0) block, but both the IF and the ELSE had the same content, these two lines: state.dataRoomAirMod->AirModel(ZoneNum).AirModelName = "MIXING AIR MODEL FOR " + state.dataHeatBal->Zone(ZoneNum).Name; state.dataRoomAirMod->AirModel(ZoneNum).ZoneName = state.dataHeatBal->Zone(ZoneNum).Name; + // set global flag for non-mixing model + if (state.dataRoomAirMod->AirModel(ZoneNum).AirModelType != DataRoomAirModel::RoomAirModel::Mixing) { + state.dataRoomAirMod->anyNonMixingRoomAirModel = true; + } + } + + if (state.dataRoomAirMod->anyNonMixingRoomAirModel) { + if (state.dataHeatBal->doSpaceHeatBalanceSimulation || state.dataHeatBal->doSpaceHeatBalanceSizing) { + ShowSevereError(state, "Non-Mixing RoomAirModelType is not supported with ZoneAirHeatBalanceAlgorithm Space Heat Balance."); + ErrorsFound = true; + } } // Write RoomAir Model details onto EIO file @@ -4796,12 +4741,13 @@ void ReportZoneMeanAirTemp(EnergyPlusData &state) Real64 thisMRTFraction; // temp working value for radiative fraction/weight for (ZoneLoop = 1; ZoneLoop <= state.dataGlobal->NumOfZones; ++ZoneLoop) { + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneLoop); // The mean air temperature is actually ZTAV which is the average // temperature of the air temperatures at the system time step for the // entire zone time step. - state.dataHeatBal->ZnAirRpt(ZoneLoop).MeanAirTemp = state.dataHeatBalFanSys->ZTAV(ZoneLoop); - state.dataHeatBal->ZnAirRpt(ZoneLoop).MeanAirHumRat = state.dataHeatBalFanSys->ZoneAirHumRatAvg(ZoneLoop); - state.dataHeatBal->ZnAirRpt(ZoneLoop).OperativeTemp = 0.5 * (state.dataHeatBalFanSys->ZTAV(ZoneLoop) + state.dataHeatBal->ZoneMRT(ZoneLoop)); + state.dataHeatBal->ZnAirRpt(ZoneLoop).MeanAirTemp = thisZoneHB.ZTAV; + state.dataHeatBal->ZnAirRpt(ZoneLoop).MeanAirHumRat = thisZoneHB.ZoneAirHumRatAvg; + state.dataHeatBal->ZnAirRpt(ZoneLoop).OperativeTemp = 0.5 * (thisZoneHB.ZTAV + state.dataHeatBal->ZoneMRT(ZoneLoop)); state.dataHeatBal->ZnAirRpt(ZoneLoop).MeanAirDewPointTemp = PsyTdpFnWPb(state, state.dataHeatBal->ZnAirRpt(ZoneLoop).MeanAirHumRat, state.dataEnvrn->OutBaroPress); @@ -4820,7 +4766,7 @@ void ReportZoneMeanAirTemp(EnergyPlusData &state) thisMRTFraction = state.dataZoneCtrls->TempControlledZone(TempControlledZoneID).FixedRadiativeFraction; } state.dataHeatBal->ZnAirRpt(ZoneLoop).ThermOperativeTemp = - (1.0 - thisMRTFraction) * state.dataHeatBalFanSys->ZTAV(ZoneLoop) + thisMRTFraction * state.dataHeatBal->ZoneMRT(ZoneLoop); + (1.0 - thisMRTFraction) * thisZoneHB.ZTAV + thisMRTFraction * state.dataHeatBal->ZoneMRT(ZoneLoop); } } } diff --git a/src/EnergyPlus/HeatBalanceHAMTManager.cc b/src/EnergyPlus/HeatBalanceHAMTManager.cc index ab8b505e7c0..65cef8e92e3 100644 --- a/src/EnergyPlus/HeatBalanceHAMTManager.cc +++ b/src/EnergyPlus/HeatBalanceHAMTManager.cc @@ -57,7 +57,6 @@ #include #include #include -#include #include #include #include @@ -71,6 +70,7 @@ #include #include #include +#include namespace EnergyPlus { @@ -1150,6 +1150,7 @@ namespace HeatBalanceHAMTManager { // Set all the boundary values cells(state.dataHeatBalHAMTMgr->ExtRadcell(sid)).temp = state.dataMstBal->TempOutsideAirFD(sid); cells(state.dataHeatBalHAMTMgr->ExtConcell(sid)).temp = state.dataMstBal->TempOutsideAirFD(sid); + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataSurface->Surface(sid).Zone); if (state.dataSurface->Surface(sid).ExtBoundCond == OtherSideCondModeledExt) { // CR8046 switch modeled rad temp for sky temp. cells(state.dataHeatBalHAMTMgr->ExtSkycell(sid)).temp = state.dataSurface->OSCM(state.dataSurface->Surface(sid).OSCMPtr).TRad; @@ -1165,7 +1166,7 @@ namespace HeatBalanceHAMTManager { // Special case when the surface is an internal mass if (state.dataSurface->Surface(sid).ExtBoundCond == sid) { - cells(state.dataHeatBalHAMTMgr->ExtConcell(sid)).temp = state.dataHeatBalFanSys->MAT(state.dataSurface->Surface(sid).Zone); + cells(state.dataHeatBalHAMTMgr->ExtConcell(sid)).temp = thisZoneHB.MAT; RhoOut = state.dataMstBal->RhoVaporAirIn(sid); } @@ -1176,7 +1177,7 @@ namespace HeatBalanceHAMTManager { cells(state.dataHeatBalHAMTMgr->ExtSkycell(sid)).htc = state.dataMstBal->HSkyFD(sid); cells(state.dataHeatBalHAMTMgr->ExtGrncell(sid)).htc = state.dataMstBal->HGrndFD(sid); - cells(state.dataHeatBalHAMTMgr->IntConcell(sid)).temp = state.dataHeatBalFanSys->MAT(state.dataSurface->Surface(sid).Zone); + cells(state.dataHeatBalHAMTMgr->IntConcell(sid)).temp = thisZoneHB.MAT; cells(state.dataHeatBalHAMTMgr->IntConcell(sid)).htc = state.dataMstBal->HConvInFD(sid); @@ -1212,15 +1213,13 @@ namespace HeatBalanceHAMTManager { if (state.dataHeatBalHAMTMgr->intvtcflag(sid)) { cells(state.dataHeatBalHAMTMgr->IntConcell(sid)).vtc = state.dataHeatBalHAMTMgr->intvtc(sid); - state.dataMstBal->HMassConvInFD(sid) = cells(state.dataHeatBalHAMTMgr->IntConcell(sid)).vtc * - PsyPsatFnTemp(state, state.dataHeatBalFanSys->MAT(state.dataSurface->Surface(sid).Zone)) * + state.dataMstBal->HMassConvInFD(sid) = cells(state.dataHeatBalHAMTMgr->IntConcell(sid)).vtc * PsyPsatFnTemp(state, thisZoneHB.MAT) * cells(state.dataHeatBalHAMTMgr->IntConcell(sid)).rh / RhoIn; } else { if (cells(state.dataHeatBalHAMTMgr->IntConcell(sid)).rh > 0) { cells(state.dataHeatBalHAMTMgr->IntConcell(sid)).vtc = state.dataMstBal->HMassConvInFD(sid) * RhoIn / - (PsyPsatFnTemp(state, state.dataHeatBalFanSys->MAT(state.dataSurface->Surface(sid).Zone)) * - cells(state.dataHeatBalHAMTMgr->IntConcell(sid)).rh); + (PsyPsatFnTemp(state, thisZoneHB.MAT) * cells(state.dataHeatBalHAMTMgr->IntConcell(sid)).rh); } else { cells(state.dataHeatBalHAMTMgr->IntConcell(sid)).vtc = 10000.0; } @@ -1523,8 +1522,7 @@ namespace HeatBalanceHAMTManager { SurfTempInP = cells(Intcell(sid)).rhp1 * PsyPsatFnTemp(state, cells(Intcell(sid)).tempp1); - state.dataMstBal->RhoVaporSurfIn(sid) = - SurfTempInP / (461.52 * (state.dataHeatBalFanSys->MAT(state.dataSurface->Surface(sid).Zone) + DataGlobalConstants::KelvinConv)); + state.dataMstBal->RhoVaporSurfIn(sid) = SurfTempInP / (461.52 * (thisZoneHB.MAT + DataGlobalConstants::KelvinConv)); } void UpdateHeatBalHAMT(EnergyPlusData &state, int const sid) diff --git a/src/EnergyPlus/HeatBalanceKivaManager.cc b/src/EnergyPlus/HeatBalanceKivaManager.cc index 1d9cc6ee5c9..f91bd475ce6 100644 --- a/src/EnergyPlus/HeatBalanceKivaManager.cc +++ b/src/EnergyPlus/HeatBalanceKivaManager.cc @@ -59,7 +59,6 @@ #include #include #include -#include #include #include #include diff --git a/src/EnergyPlus/HeatBalanceManager.cc b/src/EnergyPlus/HeatBalanceManager.cc index 634e2531afc..bec8e7e2598 100644 --- a/src/EnergyPlus/HeatBalanceManager.cc +++ b/src/EnergyPlus/HeatBalanceManager.cc @@ -74,6 +74,7 @@ #include #include #include +#include #include #include #include @@ -107,6 +108,7 @@ #include #include #include +#include namespace EnergyPlus { @@ -143,7 +145,6 @@ namespace HeatBalanceManager { // Using/Aliasing using namespace DataComplexFenestration; using namespace DataEnvironment; - using namespace DataHeatBalFanSys; using namespace DataHeatBalance; using namespace DataHeatBalSurface; using namespace DataRoomAirModel; @@ -200,6 +201,7 @@ namespace HeatBalanceManager { // Get the heat balance input at the beginning of the simulation only if (state.dataHeatBalMgr->ManageHeatBalanceGetInputFlag) { GetHeatBalanceInput(state); // Obtains heat balance related parameters from input file + if (state.dataGlobal->DoingSizing) state.dataHeatBal->doSpaceHeatBalance = state.dataHeatBal->doSpaceHeatBalanceSizing; HeatBalanceIntRadExchange::InitSolarViewFactors(state); // Surface octree setup @@ -1063,6 +1065,12 @@ namespace HeatBalanceManager { } } } + if (!state.dataIPShortCut->lAlphaFieldBlanks(2)) { + state.dataHeatBal->doSpaceHeatBalanceSizing = static_cast(getYesNoValue(AlphaName(2))); + } + if (!state.dataIPShortCut->lAlphaFieldBlanks(3)) { + state.dataHeatBal->doSpaceHeatBalanceSimulation = static_cast(getYesNoValue(AlphaName(3))); + } } else { state.dataHeatBal->ZoneAirSolutionAlgo = DataHeatBalance::SolutionAlgo::ThirdOrder; AlphaName(1) = "ThirdOrderBackwardDifference"; @@ -1073,11 +1081,15 @@ namespace HeatBalanceManager { } // Write Solution Algorithm to the initialization output file for User Verification - constexpr const char *Format_726( - "! , Value {{ThirdOrderBackwardDifference | AnalyticalSolution | EulerMethod}}\n"); + constexpr const char *Format_726("! , Algorithm {{ThirdOrderBackwardDifference | AnalyticalSolution | " + "EulerMethod}}, Space Heat Balance Sizing, Space Heat Balance Simulation\n"); print(state.files.eio, Format_726); - constexpr const char *Format_727(" Zone Air Solution Algorithm, {}\n"); - print(state.files.eio, Format_727, AlphaName(1)); + constexpr const char *Format_727(" Zone Air Solution Algorithm, {}, {}, {}\n"); + print(state.files.eio, + Format_727, + AlphaName(1), + state.dataHeatBal->doSpaceHeatBalanceSizing ? "Yes" : "No", + state.dataHeatBal->doSpaceHeatBalanceSimulation ? "Yes" : "No"); // A new object is added by L. Gu, 06/10 state.dataHeatBalMgr->CurrentModuleObject = "ZoneAirContaminantBalance"; @@ -5373,7 +5385,6 @@ namespace HeatBalanceManager { for (Loop = 1; Loop <= TotZoneEnv; ++Loop) { if (state.dataHeatBal->ZoneLocalEnvironment(Loop).ZonePtr == ZoneLoop) { if (state.dataHeatBal->ZoneLocalEnvironment(Loop).OutdoorAirNodePtr != 0) { - state.dataHeatBal->Zone(ZoneLoop).HasLinkedOutAirNode = true; state.dataHeatBal->Zone(ZoneLoop).LinkedOutAirNode = state.dataHeatBal->ZoneLocalEnvironment(Loop).OutdoorAirNodePtr; } } @@ -5723,7 +5734,6 @@ namespace HeatBalanceManager { using WindowEquivalentLayer::InitEquivalentLayerWindowCalculations; int StormWinNum; // Number of StormWindow object - int ZoneNum; if (state.dataGlobal->BeginSimFlag) { AllocateHeatBalArrays(state); // Allocate the Module Arrays @@ -5788,14 +5798,17 @@ namespace HeatBalanceManager { state.dataHeatBalMgr->ChangeSet = true; } for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceFirst; - int const lastSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceLast; - for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { - if (state.dataSurface->SurfWinStormWinFlag(SurfNum) == 1 && - state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::Detailed) { - state.dataSurface->SurfActiveConstruction(SurfNum) = state.dataSurface->SurfWinStormWinConstr(SurfNum); - } else { - state.dataSurface->SurfActiveConstruction(SurfNum) = state.dataSurface->Surface(SurfNum).Construction; + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurfWin = thisSpace.WindowSurfaceFirst; + int const lastSurfWin = thisSpace.WindowSurfaceLast; + for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { + if (state.dataSurface->SurfWinStormWinFlag(SurfNum) == 1 && + state.dataSurface->SurfWinWindowModelType(SurfNum) == DataSurfaces::WindowModel::Detailed) { + state.dataSurface->SurfActiveConstruction(SurfNum) = state.dataSurface->SurfWinStormWinConstr(SurfNum); + } else { + state.dataSurface->SurfActiveConstruction(SurfNum) = state.dataSurface->Surface(SurfNum).Construction; + } } } } @@ -5860,8 +5873,8 @@ namespace HeatBalanceManager { // Set zone data to linked air node value if defined. if (state.dataGlobal->AnyLocalEnvironmentsInModel) { SetOutAirNodes(state); - for (ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { - if (state.dataHeatBal->Zone(ZoneNum).HasLinkedOutAirNode) { + for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { + if (state.dataHeatBal->Zone(ZoneNum).LinkedOutAirNode > 0) { if (state.dataLoopNodes->Node(state.dataHeatBal->Zone(ZoneNum).LinkedOutAirNode).OutAirDryBulbSchedNum > 0) { state.dataHeatBal->Zone(ZoneNum).OutDryBulbTemp = GetCurrentScheduleValue( state, state.dataLoopNodes->Node(state.dataHeatBal->Zone(ZoneNum).LinkedOutAirNode).OutAirDryBulbSchedNum); @@ -5896,7 +5909,7 @@ namespace HeatBalanceManager { // Overwriting surface and zone level environmental data with EMS override value if (state.dataGlobal->AnyEnergyManagementSystemInModel) { - for (ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { + for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { if (state.dataHeatBal->Zone(ZoneNum).OutDryBulbTempEMSOverrideOn) { state.dataHeatBal->Zone(ZoneNum).OutDryBulbTemp = state.dataHeatBal->Zone(ZoneNum).OutDryBulbTempEMSOverrideValue; } @@ -5914,12 +5927,15 @@ namespace HeatBalanceManager { if (state.dataGlobal->BeginSimFlag) { for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceFirst; - int const lastSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceLast; - for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { - if (state.dataSurface->SurfWinWindowModelType(SurfNum) != DataSurfaces::WindowModel::BSDF && - state.dataSurface->SurfWinWindowModelType(SurfNum) != DataSurfaces::WindowModel::EQL) { - state.dataSurface->SurfWinWindowModelType(SurfNum) = DataSurfaces::WindowModel::Detailed; + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurfWin = thisSpace.WindowSurfaceFirst; + int const lastSurfWin = thisSpace.WindowSurfaceLast; + for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { + if (state.dataSurface->SurfWinWindowModelType(SurfNum) != DataSurfaces::WindowModel::BSDF && + state.dataSurface->SurfWinWindowModelType(SurfNum) != DataSurfaces::WindowModel::EQL) { + state.dataSurface->SurfWinWindowModelType(SurfNum) = DataSurfaces::WindowModel::Detailed; + } } } } @@ -5938,6 +5954,10 @@ namespace HeatBalanceManager { for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { state.dataHeatBal->ZoneMRT(zoneNum) = 0.0; } + state.dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(state.dataGlobal->NumOfZones); + // Always allocate spaceHeatBalance, even if doSpaceHeatBalance is false, because it's used to gather some of the zone totals + state.dataZoneTempPredictorCorrector->spaceHeatBalance.allocate(state.dataGlobal->numSpaces); + state.dataHeatBal->EnclSolQSDifSol.allocate(state.dataViewFactor->NumOfSolarEnclosures); state.dataHeatBal->EnclSolQD.allocate(state.dataViewFactor->NumOfSolarEnclosures); state.dataHeatBal->EnclSolQDforDaylight.allocate(state.dataViewFactor->NumOfSolarEnclosures); @@ -5976,55 +5996,11 @@ namespace HeatBalanceManager { state.dataHeatBalFanSys->ZoneQSteamBaseboardToPerson.dimension(state.dataGlobal->NumOfZones, 0.0); state.dataHeatBalFanSys->ZoneQElecBaseboardToPerson.dimension(state.dataGlobal->NumOfZones, 0.0); state.dataHeatBalFanSys->ZoneQCoolingPanelToPerson.dimension(state.dataGlobal->NumOfZones, 0.0); - state.dataHeatBalFanSys->XMAT.dimension(state.dataGlobal->NumOfZones, 23.0); - state.dataHeatBalFanSys->XM2T.dimension(state.dataGlobal->NumOfZones, 23.0); - state.dataHeatBalFanSys->XM3T.dimension(state.dataGlobal->NumOfZones, 23.0); - state.dataHeatBalFanSys->XM4T.dimension(state.dataGlobal->NumOfZones, 23.0); - state.dataHeatBalFanSys->DSXMAT.dimension(state.dataGlobal->NumOfZones, 23.0); - state.dataHeatBalFanSys->DSXM2T.dimension(state.dataGlobal->NumOfZones, 23.0); - state.dataHeatBalFanSys->DSXM3T.dimension(state.dataGlobal->NumOfZones, 23.0); - state.dataHeatBalFanSys->DSXM4T.dimension(state.dataGlobal->NumOfZones, 23.0); - state.dataHeatBalFanSys->XMPT.dimension(state.dataGlobal->NumOfZones, 23.0); - state.dataHeatBalFanSys->MCPI.dimension(state.dataGlobal->NumOfZones, 0.0); - state.dataHeatBalFanSys->MCPTI.dimension(state.dataGlobal->NumOfZones, 0.0); - state.dataHeatBalFanSys->MCPV.dimension(state.dataGlobal->NumOfZones, 0.0); - state.dataHeatBalFanSys->MCPTV.dimension(state.dataGlobal->NumOfZones, 0.0); - state.dataHeatBalFanSys->MCPM.dimension(state.dataGlobal->NumOfZones, 0.0); - state.dataHeatBalFanSys->MCPTM.dimension(state.dataGlobal->NumOfZones, 0.0); - state.dataHeatBalFanSys->MixingMassFlowZone.dimension(state.dataGlobal->NumOfZones, 0.0); - state.dataHeatBalFanSys->MixingMassFlowXHumRat.dimension(state.dataGlobal->NumOfZones, 0.0); state.dataHeatBalFanSys->ZoneReOrder.allocate(state.dataGlobal->NumOfZones); state.dataHeatBalFanSys->ZoneMassBalanceFlag.dimension(state.dataGlobal->NumOfZones, false); state.dataHeatBalFanSys->ZoneInfiltrationFlag.dimension(state.dataGlobal->NumOfZones, false); state.dataHeatBalFanSys->ZoneReOrder = 0; - state.dataHeatBalFanSys->ZoneLatentGain.dimension(state.dataGlobal->NumOfZones, 0.0); - state.dataHeatBalFanSys->ZoneLatentGainExceptPeople.dimension(state.dataGlobal->NumOfZones, 0.0); // Added for hybrid model - state.dataHeatBalFanSys->OAMFL.dimension(state.dataGlobal->NumOfZones, 0.0); - state.dataHeatBalFanSys->VAMFL.dimension(state.dataGlobal->NumOfZones, 0.0); - state.dataHeatBalFanSys->ZTAV.dimension(state.dataGlobal->NumOfZones, 23.0); - state.dataHeatBalFanSys->ZTAVComf.dimension(state.dataGlobal->NumOfZones, 23.0); - state.dataHeatBalFanSys->ZT.dimension(state.dataGlobal->NumOfZones, 23.0); - state.dataHeatBalFanSys->TempTstatAir.dimension(state.dataGlobal->NumOfZones, 23.0); - state.dataHeatBalFanSys->MAT.dimension(state.dataGlobal->NumOfZones, 23.0); - state.dataHeatBalFanSys->ZoneTMX.dimension(state.dataGlobal->NumOfZones, 23.0); - state.dataHeatBalFanSys->ZoneTM2.dimension(state.dataGlobal->NumOfZones, 23.0); - // Allocate this zone air humidity ratio - state.dataHeatBalFanSys->ZoneAirHumRatAvg.dimension(state.dataGlobal->NumOfZones, 0.01); - state.dataHeatBalFanSys->ZoneAirHumRatAvgComf.dimension(state.dataGlobal->NumOfZones, 0.01); - state.dataHeatBalFanSys->ZoneAirHumRat.dimension(state.dataGlobal->NumOfZones, 0.01); - state.dataHeatBalFanSys->ZoneAirHumRatOld.dimension(state.dataGlobal->NumOfZones, 0.01); - state.dataHeatBalFanSys->SumHmAW.dimension(state.dataGlobal->NumOfZones, 0.0); - state.dataHeatBalFanSys->SumHmARa.dimension(state.dataGlobal->NumOfZones, 0.0); - state.dataHeatBalFanSys->SumHmARaW.dimension(state.dataGlobal->NumOfZones, 0.0); - state.dataHeatBalFanSys->MCPTE.dimension(state.dataGlobal->NumOfZones, 0.0); - state.dataHeatBalFanSys->MCPE.dimension(state.dataGlobal->NumOfZones, 0.0); - state.dataHeatBalFanSys->EAMFL.dimension(state.dataGlobal->NumOfZones, 0.0); - state.dataHeatBalFanSys->EAMFLxHumRat.dimension(state.dataGlobal->NumOfZones, 0.0); - state.dataHeatBalFanSys->MCPTC.dimension(state.dataGlobal->NumOfZones, 0.0); - state.dataHeatBalFanSys->MCPC.dimension(state.dataGlobal->NumOfZones, 0.0); - state.dataHeatBalFanSys->CTMFL.dimension(state.dataGlobal->NumOfZones, 0.0); - state.dataHeatBalFanSys->MDotCPOA.dimension(state.dataGlobal->NumOfZones, 0.0); - state.dataHeatBalFanSys->MDotOA.dimension(state.dataGlobal->NumOfZones, 0.0); + state.dataHeatBalFanSys->TempTstatAir.dimension(state.dataGlobal->NumOfZones, DataHeatBalance::ZoneInitialTemp); if (state.dataContaminantBalance->Contaminant.CO2Simulation) { state.dataContaminantBalance->OutdoorCO2 = GetCurrentScheduleValue(state, state.dataContaminantBalance->Contaminant.CO2OutdoorSchedPtr); state.dataContaminantBalance->ZoneAirCO2.dimension(state.dataGlobal->NumOfZones, state.dataContaminantBalance->OutdoorCO2); @@ -6154,17 +6130,19 @@ namespace HeatBalanceManager { // Record Maxs & Mins for individual zone for (ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { - if (state.dataHeatBalFanSys->ZTAV(ZoneNum) > state.dataHeatBalMgr->MaxTempZone(ZoneNum)) { - state.dataHeatBalMgr->MaxTempZone(ZoneNum) = state.dataHeatBalFanSys->ZTAV(ZoneNum); + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); + auto &thisZoneSysEnergyDemand = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum); + if (thisZoneHB.ZTAV > state.dataHeatBalMgr->MaxTempZone(ZoneNum)) { + state.dataHeatBalMgr->MaxTempZone(ZoneNum) = thisZoneHB.ZTAV; } - if (state.dataHeatBalFanSys->ZTAV(ZoneNum) < state.dataHeatBalMgr->MinTempZone(ZoneNum)) { - state.dataHeatBalMgr->MinTempZone(ZoneNum) = state.dataHeatBalFanSys->ZTAV(ZoneNum); + if (thisZoneHB.ZTAV < state.dataHeatBalMgr->MinTempZone(ZoneNum)) { + state.dataHeatBalMgr->MinTempZone(ZoneNum) = thisZoneHB.ZTAV; } - if (state.dataHeatBal->ZoneSNLoadHeatRate(ZoneNum) > state.dataHeatBalMgr->MaxHeatLoadZone(ZoneNum)) { - state.dataHeatBalMgr->MaxHeatLoadZone(ZoneNum) = state.dataHeatBal->ZoneSNLoadHeatRate(ZoneNum); + if (thisZoneSysEnergyDemand.ZoneSNLoadHeatRate > state.dataHeatBalMgr->MaxHeatLoadZone(ZoneNum)) { + state.dataHeatBalMgr->MaxHeatLoadZone(ZoneNum) = thisZoneSysEnergyDemand.ZoneSNLoadHeatRate; } - if (state.dataHeatBal->ZoneSNLoadCoolRate(ZoneNum) > state.dataHeatBalMgr->MaxCoolLoadZone(ZoneNum)) { - state.dataHeatBalMgr->MaxCoolLoadZone(ZoneNum) = state.dataHeatBal->ZoneSNLoadCoolRate(ZoneNum); + if (thisZoneSysEnergyDemand.ZoneSNLoadCoolRate > state.dataHeatBalMgr->MaxCoolLoadZone(ZoneNum)) { + state.dataHeatBalMgr->MaxCoolLoadZone(ZoneNum) = thisZoneSysEnergyDemand.ZoneSNLoadCoolRate; } // Record temperature and load for individual zone @@ -6172,9 +6150,9 @@ namespace HeatBalanceManager { state.dataHeatBalMgr->LoadZoneSecPrevDay(ZoneNum) = state.dataHeatBalMgr->LoadZonePrevDay(ZoneNum); state.dataHeatBalMgr->TempZonePrevDay(ZoneNum) = state.dataHeatBalMgr->TempZone(ZoneNum); state.dataHeatBalMgr->LoadZonePrevDay(ZoneNum) = state.dataHeatBalMgr->LoadZone(ZoneNum); - state.dataHeatBalMgr->TempZone(ZoneNum) = state.dataHeatBalFanSys->ZTAV(ZoneNum); + state.dataHeatBalMgr->TempZone(ZoneNum) = thisZoneHB.ZTAV; state.dataHeatBalMgr->LoadZone(ZoneNum) = - max(state.dataHeatBal->ZoneSNLoadHeatRate(ZoneNum), std::abs(state.dataHeatBal->ZoneSNLoadCoolRate(ZoneNum))); + max(thisZoneSysEnergyDemand.ZoneSNLoadHeatRate, std::abs(thisZoneSysEnergyDemand.ZoneSNLoadCoolRate)); // Calculate differences in temperature and load for the last two warmup days if (!state.dataGlobal->WarmupFlag && state.dataGlobal->DayOfSim == 1 && @@ -8447,8 +8425,6 @@ namespace HeatBalanceManager { // na // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int iSurf; - int iConst; int SchedPtr; // scheduled surface gains pointer bool ZoneUnscheduled; // true if all surfaces in the zone are unscheduled bool ZoneScheduled; // true if all surfaces in the zone are scheduled @@ -8456,51 +8432,56 @@ namespace HeatBalanceManager { ZoneUnscheduled = false; ZoneScheduled = false; - for (iSurf = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst; iSurf <= state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast; ++iSurf) { - iConst = state.dataSurface->Surface(iSurf).Construction; - if (state.dataSurface->Surface(iSurf).Class == SurfaceClass::Window) { - SchedPtr = WindowScheduledSolarAbs(state, iSurf, iConst); - } else { - SchedPtr = SurfaceScheduledSolarInc(state, iSurf, iConst); - } - if (iSurf == state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst) { - if (SchedPtr != 0) { - ZoneScheduled = true; - ZoneUnscheduled = false; + bool firstZoneSurface = true; + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int iSurf = thisSpace.HTSurfaceFirst; iSurf <= thisSpace.HTSurfaceLast; ++iSurf) { + int iConst = state.dataSurface->Surface(iSurf).Construction; + if (state.dataSurface->Surface(iSurf).Class == SurfaceClass::Window) { + SchedPtr = WindowScheduledSolarAbs(state, iSurf, iConst); } else { - ZoneScheduled = false; - ZoneUnscheduled = true; + SchedPtr = SurfaceScheduledSolarInc(state, iSurf, iConst); } - } else { - if (SchedPtr != 0) { - ZoneUnscheduled = false; + if (firstZoneSurface) { + if (SchedPtr != 0) { + ZoneScheduled = true; + ZoneUnscheduled = false; + } else { + ZoneScheduled = false; + ZoneUnscheduled = true; + } + firstZoneSurface = false; } else { - ZoneScheduled = false; + if (SchedPtr != 0) { + ZoneUnscheduled = false; + } else { + ZoneScheduled = false; + } } } - - if ((!ZoneScheduled) && (!ZoneUnscheduled)) { - // zone is nor scheduled nor unscheduled - ShowWarningError(state, - "Zone " + state.dataHeatBal->Zone(ZoneNum).Name + " does not have all surfaces scheduled with surface gains."); - ShowContinueError(state, - "If at least one surface in the zone is scheduled with surface gains, then all other surfaces within the same zone " - "should be scheduled as well."); - break; - } + } + if ((!ZoneScheduled) && (!ZoneUnscheduled)) { + // zone is nor scheduled nor unscheduled + ShowWarningError(state, "Zone " + state.dataHeatBal->Zone(ZoneNum).Name + " does not have all surfaces scheduled with surface gains."); + ShowContinueError(state, + "If at least one surface in the zone is scheduled with surface gains, then all other surfaces within the same zone " + "should be scheduled as well."); } if ((!ZoneScheduled) && (!ZoneUnscheduled)) { - for (iSurf = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst; iSurf <= state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast; ++iSurf) { - iConst = state.dataSurface->Surface(iSurf).Construction; - if (state.dataSurface->Surface(iSurf).Class == SurfaceClass::Window) { - SchedPtr = WindowScheduledSolarAbs(state, iSurf, iConst); - } else { - SchedPtr = SurfaceScheduledSolarInc(state, iSurf, iConst); - } + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int iSurf = thisSpace.HTSurfaceFirst; iSurf <= thisSpace.HTSurfaceLast; ++iSurf) { + int iConst = state.dataSurface->Surface(iSurf).Construction; + if (state.dataSurface->Surface(iSurf).Class == SurfaceClass::Window) { + SchedPtr = WindowScheduledSolarAbs(state, iSurf, iConst); + } else { + SchedPtr = SurfaceScheduledSolarInc(state, iSurf, iConst); + } - if (SchedPtr == 0) { - ShowContinueError(state, "Surface " + state.dataSurface->Surface(iSurf).Name + " does not have scheduled surface gains."); + if (SchedPtr == 0) { + ShowContinueError(state, "Surface " + state.dataSurface->Surface(iSurf).Name + " does not have scheduled surface gains."); + } } } } diff --git a/src/EnergyPlus/HeatBalanceSurfaceManager.cc b/src/EnergyPlus/HeatBalanceSurfaceManager.cc index bfe49b0f9de..2afbeee9856 100644 --- a/src/EnergyPlus/HeatBalanceSurfaceManager.cc +++ b/src/EnergyPlus/HeatBalanceSurfaceManager.cc @@ -116,6 +116,7 @@ #include #include #include +#include #include #include #include @@ -149,7 +150,6 @@ namespace EnergyPlus::HeatBalanceSurfaceManager { // Use statements for data only modules // Using/Aliasing using namespace DataEnvironment; -using namespace DataHeatBalFanSys; using namespace DataHeatBalance; using namespace DataHeatBalSurface; using namespace DataSurfaces; @@ -299,7 +299,7 @@ void InitSurfaceHeatBalance(EnergyPlusData &state) // END DO if (state.dataGlobal->AnyLocalEnvironmentsInModel) { for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) { - if (state.dataSurface->Surface(SurfNum).SurfHasLinkedOutAirNode) { + if (state.dataSurface->Surface(SurfNum).SurfLinkedOutAirNode > 0) { auto &linkedNode = state.dataLoopNodes->Node(state.dataSurface->Surface(SurfNum).SurfLinkedOutAirNode); state.dataSurface->SurfOutDryBulbTemp(SurfNum) = linkedNode.OutAirDryBulb; state.dataSurface->SurfOutWetBulbTemp(SurfNum) = linkedNode.OutAirWetBulb; @@ -336,21 +336,21 @@ void InitSurfaceHeatBalance(EnergyPlusData &state) std::any_of(state.dataViewFactor->EnclSolInfo.begin(), state.dataViewFactor->EnclSolInfo.end(), [](DataViewFactorInformation::EnclosureViewFactorInformation const &e) { return e.HasInterZoneWindow; }); - state.dataRoomAirMod->IsZoneDV.dimension(state.dataGlobal->NumOfZones, false); - state.dataRoomAirMod->IsZoneCV.dimension(state.dataGlobal->NumOfZones, false); - state.dataRoomAirMod->IsZoneUI.dimension(state.dataGlobal->NumOfZones, false); } if (state.dataGlobal->BeginSimFlag || state.dataGlobal->AnySurfPropOverridesInModel) { for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurf = state.dataHeatBal->Zone(zoneNum).HTSurfaceFirst; - int const lastSurf = state.dataHeatBal->Zone(zoneNum).HTSurfaceLast; - for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) { - int ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); // SurfActiveConstruction set above - state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = state.dataConstruction->Construct(ConstrNum).InsideAbsorpSolar; - state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = state.dataConstruction->Construct(ConstrNum).InsideAbsorpThermal; - state.dataHeatBalSurf->SurfRoughnessExt(SurfNum) = state.dataConstruction->Construct(ConstrNum).OutsideRoughness; - state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = state.dataConstruction->Construct(ConstrNum).OutsideAbsorpSolar; - state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum) = state.dataConstruction->Construct(ConstrNum).OutsideAbsorpThermal; + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurf = thisSpace.HTSurfaceFirst; + int const lastSurf = thisSpace.HTSurfaceLast; + for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) { + int ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); // SurfActiveConstruction set above + state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum) = state.dataConstruction->Construct(ConstrNum).InsideAbsorpSolar; + state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = state.dataConstruction->Construct(ConstrNum).InsideAbsorpThermal; + state.dataHeatBalSurf->SurfRoughnessExt(SurfNum) = state.dataConstruction->Construct(ConstrNum).OutsideRoughness; + state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum) = state.dataConstruction->Construct(ConstrNum).OutsideAbsorpSolar; + state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum) = state.dataConstruction->Construct(ConstrNum).OutsideAbsorpThermal; + } } } } @@ -445,106 +445,115 @@ void InitSurfaceHeatBalance(EnergyPlusData &state) } for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces... - int const firstSurfOpaque = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceFirst; - int const lastSurfOpaque = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceLast; - for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) { - auto const &surface(Surface(SurfNum)); - if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF && - surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD) - continue; - // Outside surface temp of "normal" windows not needed in Window5 calculation approach - // Window layer temperatures are calculated in CalcHeatBalanceInsideSurf - - int const ConstrNum = surface.Construction; - auto const &construct(state.dataConstruction->Construct(ConstrNum)); - state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) = 0.0; - if (construct.NumCTFTerms <= 1) continue; - - for (int Term = 1; Term <= construct.NumCTFTerms; ++Term) { - // [ l11 ] == ( 1, Term + 1, SurfNum ), [ l12 ] == ( 1, Term + 1, SurfNum ) - - // Sign convention for the various terms in the following two equations - // is based on the form of the Conduction Transfer Function equation - // given by: - // Qin,now = (Sum of)(Y Tout) - (Sum of)(Z Tin) + (Sum of)(F Qin,old) - // Qout,now = (Sum of)(X Tout) - (Sum of)(Y Tin) + (Sum of)(F Qout,old) - // In both equations, flux is positive from outside to inside. - - // Tuned Aliases and linear indexing - Real64 const ctf_cross(construct.CTFCross(Term)); - - Real64 const TH11(state.dataHeatBalSurf->SurfOutsideTempHist(Term + 1)(SurfNum)); - Real64 const TH12(state.dataHeatBalSurf->SurfInsideTempHist(Term + 1)(SurfNum)); - Real64 const QH11(state.dataHeatBalSurf->SurfOutsideFluxHist(Term + 1)(SurfNum)); - Real64 const QH12(state.dataHeatBalSurf->SurfInsideFluxHist(Term + 1)(SurfNum)); - state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) += - ctf_cross * TH11 - construct.CTFInside(Term) * TH12 + construct.CTFFlux(Term) * QH12; - - state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) += - construct.CTFOutside(Term) * TH11 - ctf_cross * TH12 + construct.CTFFlux(Term) * QH11; - } - } - } - if (state.dataHeatBal->AnyInternalHeatSourceInInput) { - for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces... - int const firstSurfOpaque = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceFirst; - int const lastSurfOpaque = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceLast; + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst; + int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast; for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) { auto const &surface(Surface(SurfNum)); - int const ConstrNum = surface.Construction; - auto const &construct(state.dataConstruction->Construct(ConstrNum)); - if (!construct.SourceSinkPresent) continue; if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF && surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD) continue; - state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum) = 0.0; - state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum) = 0.0; + // Outside surface temp of "normal" windows not needed in Window5 calculation approach + // Window layer temperatures are calculated in CalcHeatBalanceInsideSurf + + int const ConstrNum = surface.Construction; + auto const &construct(state.dataConstruction->Construct(ConstrNum)); + state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) = 0.0; if (construct.NumCTFTerms <= 1) continue; + for (int Term = 1; Term <= construct.NumCTFTerms; ++Term) { - Real64 const TH11(state.dataHeatBalSurf->SurfOutsideTempHist(Term + 1)(SurfNum)); - Real64 const TH12(state.dataHeatBalSurf->SurfInsideTempHist(Term + 1)(SurfNum)); - Real64 const QsrcHist1(state.dataHeatBalSurf->SurfQsrcHist(SurfNum, Term + 1)); + // [ l11 ] == ( 1, Term + 1, SurfNum ), [ l12 ] == ( 1, Term + 1, SurfNum ) - state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) += construct.CTFSourceIn(Term) * QsrcHist1; + // Sign convention for the various terms in the following two equations + // is based on the form of the Conduction Transfer Function equation + // given by: + // Qin,now = (Sum of)(Y Tout) - (Sum of)(Z Tin) + (Sum of)(F Qin,old) + // Qout,now = (Sum of)(X Tout) - (Sum of)(Y Tin) + (Sum of)(F Qout,old) + // In both equations, flux is positive from outside to inside. - state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) += construct.CTFSourceOut(Term) * QsrcHist1; + // Tuned Aliases and linear indexing + Real64 const ctf_cross(construct.CTFCross(Term)); - state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum) += - construct.CTFTSourceOut(Term) * TH11 + construct.CTFTSourceIn(Term) * TH12 + construct.CTFTSourceQ(Term) * QsrcHist1 + - construct.CTFFlux(Term) * state.dataHeatBalSurf->SurfTsrcHist(SurfNum, Term + 1); + Real64 const TH11(state.dataHeatBalSurf->SurfOutsideTempHist(Term + 1)(SurfNum)); + Real64 const TH12(state.dataHeatBalSurf->SurfInsideTempHist(Term + 1)(SurfNum)); + Real64 const QH11(state.dataHeatBalSurf->SurfOutsideFluxHist(Term + 1)(SurfNum)); + Real64 const QH12(state.dataHeatBalSurf->SurfInsideFluxHist(Term + 1)(SurfNum)); + state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) += + ctf_cross * TH11 - construct.CTFInside(Term) * TH12 + construct.CTFFlux(Term) * QH12; - state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum) += - construct.CTFTUserOut(Term) * TH11 + construct.CTFTUserIn(Term) * TH12 + construct.CTFTUserSource(Term) * QsrcHist1 + - construct.CTFFlux(Term) * state.dataHeatBalSurf->SurfTuserHist(SurfNum, Term + 1); + state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) += + construct.CTFOutside(Term) * TH11 - ctf_cross * TH12 + construct.CTFFlux(Term) * QH11; } } - } // ...end of surfaces DO loop for initializing temperature history terms for the surface heat balances + } + } + if (state.dataHeatBal->AnyInternalHeatSourceInInput) { + for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces... + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst; + int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast; + for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) { + auto const &surface(Surface(SurfNum)); + int const ConstrNum = surface.Construction; + auto const &construct(state.dataConstruction->Construct(ConstrNum)); + if (!construct.SourceSinkPresent) continue; + if (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF && + surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD) + continue; + state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum) = 0.0; + state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum) = 0.0; + if (construct.NumCTFTerms <= 1) continue; + for (int Term = 1; Term <= construct.NumCTFTerms; ++Term) { + Real64 const TH11(state.dataHeatBalSurf->SurfOutsideTempHist(Term + 1)(SurfNum)); + Real64 const TH12(state.dataHeatBalSurf->SurfInsideTempHist(Term + 1)(SurfNum)); + Real64 const QsrcHist1(state.dataHeatBalSurf->SurfQsrcHist(SurfNum, Term + 1)); + + state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) += construct.CTFSourceIn(Term) * QsrcHist1; + + state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum) += construct.CTFSourceOut(Term) * QsrcHist1; + + state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum) += + construct.CTFTSourceOut(Term) * TH11 + construct.CTFTSourceIn(Term) * TH12 + construct.CTFTSourceQ(Term) * QsrcHist1 + + construct.CTFFlux(Term) * state.dataHeatBalSurf->SurfTsrcHist(SurfNum, Term + 1); + + state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum) += + construct.CTFTUserOut(Term) * TH11 + construct.CTFTUserIn(Term) * TH12 + construct.CTFTUserSource(Term) * QsrcHist1 + + construct.CTFFlux(Term) * state.dataHeatBalSurf->SurfTuserHist(SurfNum, Term + 1); + } + } + } // ...end of surfaces DO loop for initializing temperature history terms for the surface heat balances + } } // Zero out all of the radiant system heat balance coefficient arrays for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces... - int const firstSurf = state.dataHeatBal->Zone(zoneNum).HTSurfaceFirst; - int const lastSurf = state.dataHeatBal->Zone(zoneNum).HTSurfaceLast; - for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) { - state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum) = 0.0; - state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum) = 0.0; - state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum) = 0.0; - state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = 0.0; - state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) = 0.0; - state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) = 0.0; - - state.dataHeatBalFanSys->QRadSysSource(SurfNum) = 0.0; - state.dataHeatBalFanSys->QPVSysSource(SurfNum) = 0.0; - state.dataHeatBalFanSys->SurfQHTRadSys(SurfNum) = 0.0; - state.dataHeatBalFanSys->SurfQHWBaseboard(SurfNum) = 0.0; - state.dataHeatBalFanSys->SurfQSteamBaseboard(SurfNum) = 0.0; - state.dataHeatBalFanSys->SurfQElecBaseboard(SurfNum) = 0.0; - state.dataHeatBalFanSys->SurfQCoolingPanel(SurfNum) = 0.0; - state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) = 0.0; - state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) = 0.0; - } // ...end of Zone Surf loop - } // ...end of Zone loop + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurf = thisSpace.HTSurfaceFirst; + int const lastSurf = thisSpace.HTSurfaceLast; + for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) { + state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum) = 0.0; + state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum) = 0.0; + state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum) = 0.0; + state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = 0.0; + state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum) = 0.0; + state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum) = 0.0; + + state.dataHeatBalFanSys->QRadSysSource(SurfNum) = 0.0; + state.dataHeatBalFanSys->QPVSysSource(SurfNum) = 0.0; + state.dataHeatBalFanSys->SurfQHTRadSys(SurfNum) = 0.0; + state.dataHeatBalFanSys->SurfQHWBaseboard(SurfNum) = 0.0; + state.dataHeatBalFanSys->SurfQSteamBaseboard(SurfNum) = 0.0; + state.dataHeatBalFanSys->SurfQElecBaseboard(SurfNum) = 0.0; + state.dataHeatBalFanSys->SurfQCoolingPanel(SurfNum) = 0.0; + state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) = 0.0; + state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) = 0.0; + } // ...end of Zone Surf loop + } + } // ...end of Zone loop if (state.dataGlobal->ZoneSizingCalc) GatherComponentLoadsSurfAbsFact(state); @@ -1265,21 +1274,10 @@ void AllocateSurfaceHeatBalArrays(EnergyPlusData &state) // SUBROUTINE INFORMATION: // AUTHOR Richard Liesen // DATE WRITTEN February 1998 - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS SUBROUTINE: - // This subroutine // METHODOLOGY EMPLOYED: // Uses the status flags to trigger variable allocation. - // REFERENCES: - // na - - // USE STATEMENTS: - // USE DataRoomAirModel, ONLY: IsZoneDV,IsZoneCV,HVACMassFlow, ZoneDVMixedFlag - auto &Surface(state.dataSurface->Surface); // Use the total number of surfaces to allocate variables to avoid a surface number limit @@ -1300,7 +1298,7 @@ void AllocateSurfaceHeatBalArrays(EnergyPlusData &state) state.dataHeatBalFanSys->CTFTuserConstPart.dimension(state.dataSurface->TotSurfaces, 0.0); } - state.dataHeatBal->SurfTempEffBulkAir.dimension(state.dataSurface->TotSurfaces, ZoneInitialTemp); + state.dataHeatBal->SurfTempEffBulkAir.dimension(state.dataSurface->TotSurfaces, DataHeatBalance::ZoneInitialTemp); state.dataHeatBalSurf->SurfHConvInt.dimension(state.dataSurface->TotSurfaces, 0.0); state.dataHeatBalSurf->SurfHcExt.dimension(state.dataSurface->TotSurfaces, 0.0); state.dataHeatBalSurf->SurfHAirExt.dimension(state.dataSurface->TotSurfaces, 0.0); @@ -2113,142 +2111,146 @@ void InitThermalAndFluxHistories(EnergyPlusData &state) // First do the "bulk" initializations of arrays sized to NumOfZones for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - state.dataHeatBal->ZoneMRT(zoneNum) = ZoneInitialTemp; // module level array - state.dataHeatBalFanSys->MAT(zoneNum) = ZoneInitialTemp; // DataHeatBalFanSys array - state.dataHeatBalFanSys->ZT(zoneNum) = ZoneInitialTemp; - state.dataHeatBalFanSys->ZTAV(zoneNum) = ZoneInitialTemp; - state.dataHeatBalFanSys->XMAT(zoneNum) = ZoneInitialTemp; // DataHeatBalFanSys array - state.dataHeatBalFanSys->XM2T(zoneNum) = ZoneInitialTemp; // DataHeatBalFanSys array - state.dataHeatBalFanSys->XM3T(zoneNum) = ZoneInitialTemp; // DataHeatBalFanSys array - state.dataHeatBalFanSys->XM4T(zoneNum) = ZoneInitialTemp; - state.dataHeatBalFanSys->XMPT(zoneNum) = ZoneInitialTemp; - state.dataHeatBalFanSys->DSXMAT(zoneNum) = ZoneInitialTemp; // DataHeatBalFanSys array - state.dataHeatBalFanSys->DSXM2T(zoneNum) = ZoneInitialTemp; // DataHeatBalFanSys array - state.dataHeatBalFanSys->DSXM3T(zoneNum) = ZoneInitialTemp; // DataHeatBalFanSys array - state.dataHeatBalFanSys->DSXM4T(zoneNum) = ZoneInitialTemp; - state.dataHeatBalFanSys->ZoneTMX(zoneNum) = ZoneInitialTemp; // DataHeatBalFanSys array - state.dataHeatBalFanSys->ZoneTM2(zoneNum) = ZoneInitialTemp; // DataHeatBalFanSys array + state.dataHeatBal->ZoneMRT(zoneNum) = DataHeatBalance::ZoneInitialTemp; // module level array + // TODO: Reinitializing this entire struct may cause diffs + new (&state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum)) ZoneTempPredictorCorrector::ZoneHeatBalanceData(); + // Initialize the Zone Humidity Ratio here so that it is available for EMPD implementations + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum); + thisZoneHB.ZoneAirHumRatAvg = state.dataEnvrn->OutHumRat; + thisZoneHB.ZoneAirHumRat = state.dataEnvrn->OutHumRat; + state.dataHeatBalFanSys->TempTstatAir(zoneNum) = DataHeatBalance::ZoneInitialTemp; + } + // Reset spaceHeatBalance even if doSpaceHeatBalance is false, beause spaceHB is used to gether zoneHB in some cases + for (auto &thisSpaceHB : state.dataZoneTempPredictorCorrector->spaceHeatBalance) { + new (&thisSpaceHB) ZoneTempPredictorCorrector::SpaceHeatBalanceData(); // Initialize the Zone Humidity Ratio here so that it is available for EMPD implementations - state.dataHeatBalFanSys->ZoneAirHumRatAvg(zoneNum) = state.dataEnvrn->OutHumRat; - state.dataHeatBalFanSys->ZoneAirHumRat(zoneNum) = state.dataEnvrn->OutHumRat; - state.dataHeatBalFanSys->ZoneAirHumRatOld(zoneNum) = state.dataEnvrn->OutHumRat; - state.dataHeatBalFanSys->SumHmAW(zoneNum) = 0.0; - state.dataHeatBalFanSys->SumHmARa(zoneNum) = 0.0; - state.dataHeatBalFanSys->SumHmARaW(zoneNum) = 0.0; - state.dataHeatBalFanSys->TempTstatAir(zoneNum) = ZoneInitialTemp; + thisSpaceHB.ZoneAirHumRatAvg = state.dataEnvrn->OutHumRat; + thisSpaceHB.ZoneAirHumRat = state.dataEnvrn->OutHumRat; } // "Bulk" initializations of arrays sized to TotSurfaces for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurf = state.dataHeatBal->Zone(zoneNum).HTSurfaceFirst; - int const lastSurf = state.dataHeatBal->Zone(zoneNum).HTSurfaceLast; - for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) { - state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = SurfInitialTemp; - state.dataHeatBalSurf->SurfTempIn(SurfNum) = SurfInitialTemp; // module level array - state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = SurfInitialTemp; // module level array - state.dataHeatBalSurf->SurfHConvInt(SurfNum) = SurfInitialConvCoeff; // module level array - state.dataHeatBalSurf->SurfHcExt(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfHAirExt(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfHSkyExt(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfHGrdExt(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfTempOut(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfTempInMovInsRep(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfQConvInReport(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfQdotConvInRep(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfQdotConvInPerArea(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfQRadNetSurfInReport(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfQRadSolarInReport(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfQdotRadSolarInRep(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfQRadLightsInReport(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfQdotRadLightsInRep(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfQRadIntGainsInReport(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(SurfNum) = 0.0; - state.dataHeatBalSurf->AnyRadiantSystems(SurfNum) = false; - state.dataHeatBalSurf->SurfQRadHVACInReport(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfQdotRadHVACInRep(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfQConvOutReport(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfQdotConvOutRep(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfQdotConvOutPerArea(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfQRadOutReport(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfQdotRadOutRep(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfQAirExtReport(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfQHeatEmiReport(SurfNum) = 0.0; - } // end of Surf array - int const firstSurfOpaq = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceFirst; - int const lastSurfOpaq = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceLast; - if (firstSurfOpaq >= 0) { - for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) { - state.dataHeatBalSurf->SurfOpaqInsFaceCond(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) = 0.0; - } // end of Zone Surf - } - int const firstSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceFirst; - int const lastSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceLast; - if (firstSurfWin >= 0) { - for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { - // Initialize window frame and divider temperatures - state.dataSurface->SurfWinFrameTempIn(SurfNum) = SurfInitialTemp; - state.dataSurface->SurfWinFrameTempInOld(SurfNum) = SurfInitialTemp; - state.dataSurface->SurfWinFrameTempSurfOut(SurfNum) = SurfInitialTemp; - state.dataSurface->SurfWinDividerTempIn(SurfNum) = SurfInitialTemp; - state.dataSurface->SurfWinDividerTempInOld(SurfNum) = SurfInitialTemp; - state.dataSurface->SurfWinDividerTempSurfOut(SurfNum) = SurfInitialTemp; - - // Initialize previous-timestep shading indicators - state.dataSurface->SurfWinExtIntShadePrevTS(SurfNum) = WinShadingType::NoShade; - state.dataSurface->SurfWinShadingFlag(SurfNum) = WinShadingType::NoShade; - } // end of Zone Surf + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurf = thisSpace.HTSurfaceFirst; + int const lastSurf = thisSpace.HTSurfaceLast; + for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) { + state.dataHeatBal->SurfTempEffBulkAir(SurfNum) = SurfInitialTemp; + state.dataHeatBalSurf->SurfTempIn(SurfNum) = SurfInitialTemp; // module level array + state.dataHeatBalSurf->SurfTempInTmp(SurfNum) = SurfInitialTemp; // module level array + state.dataHeatBalSurf->SurfHConvInt(SurfNum) = SurfInitialConvCoeff; // module level array + state.dataHeatBalSurf->SurfHcExt(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfHAirExt(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfTempOut(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfTempInMovInsRep(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfQConvInReport(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfQdotConvInRep(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfQdotConvInPerArea(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfQRadNetSurfInReport(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfQRadSolarInReport(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfQdotRadSolarInRep(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfQRadLightsInReport(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfQdotRadLightsInRep(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfQRadIntGainsInReport(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(SurfNum) = 0.0; + state.dataHeatBalSurf->AnyRadiantSystems(SurfNum) = false; + state.dataHeatBalSurf->SurfQRadHVACInReport(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfQdotRadHVACInRep(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfQConvOutReport(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfQdotConvOutRep(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfQdotConvOutPerArea(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfQRadOutReport(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfQdotRadOutRep(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfQAirExtReport(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfQHeatEmiReport(SurfNum) = 0.0; + } // end of Surf array + int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst; + int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast; + if (firstSurfOpaq >= 0) { + for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) { + state.dataHeatBalSurf->SurfOpaqInsFaceCond(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) = 0.0; + } // end of Zone Surf + } + int const firstSurfWin = thisSpace.WindowSurfaceFirst; + int const lastSurfWin = thisSpace.WindowSurfaceLast; + if (firstSurfWin >= 0) { + for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { + // Initialize window frame and divider temperatures + state.dataSurface->SurfWinFrameTempIn(SurfNum) = SurfInitialTemp; + state.dataSurface->SurfWinFrameTempInOld(SurfNum) = SurfInitialTemp; + state.dataSurface->SurfWinFrameTempSurfOut(SurfNum) = SurfInitialTemp; + state.dataSurface->SurfWinDividerTempIn(SurfNum) = SurfInitialTemp; + state.dataSurface->SurfWinDividerTempInOld(SurfNum) = SurfInitialTemp; + state.dataSurface->SurfWinDividerTempSurfOut(SurfNum) = SurfInitialTemp; + + // Initialize previous-timestep shading indicators + state.dataSurface->SurfWinExtIntShadePrevTS(SurfNum) = WinShadingType::NoShade; + state.dataSurface->SurfWinShadingFlag(SurfNum) = WinShadingType::NoShade; + } // end of Zone Surf + } } } // end of Zone // "Bulk" initializations of temperature arrays with dimensions (TotSurface,MaxCTFTerms,2) for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurf = state.dataHeatBal->Zone(zoneNum).HTSurfaceFirst; - int const lastSurf = state.dataHeatBal->Zone(zoneNum).HTSurfaceLast; - for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) { - for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) { - state.dataHeatBalSurf->SurfInsideTempHist(CTFTermNum)(SurfNum) = SurfInitialTemp; - state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) = SurfInitialTemp; - state.dataHeatBalSurf->SurfInsideFluxHist(CTFTermNum)(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfOutsideFluxHist(CTFTermNum)(SurfNum) = 0.0; + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurf = thisSpace.HTSurfaceFirst; + int const lastSurf = thisSpace.HTSurfaceLast; + for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) { + for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) { + state.dataHeatBalSurf->SurfInsideTempHist(CTFTermNum)(SurfNum) = SurfInitialTemp; + state.dataHeatBalSurf->SurfOutsideTempHist(CTFTermNum)(SurfNum) = SurfInitialTemp; + state.dataHeatBalSurf->SurfInsideFluxHist(CTFTermNum)(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfOutsideFluxHist(CTFTermNum)(SurfNum) = 0.0; + } } } } if (!state.dataHeatBal->SimpleCTFOnly || state.dataGlobal->AnyEnergyManagementSystemInModel) { for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurf = state.dataHeatBal->Zone(zoneNum).HTSurfaceFirst; - int const lastSurf = state.dataHeatBal->Zone(zoneNum).HTSurfaceLast; - for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) { - state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) = 0; - } - for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) { + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurf = thisSpace.HTSurfaceFirst; + int const lastSurf = thisSpace.HTSurfaceLast; for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) { - state.dataHeatBalSurf->SurfInsideTempHistMaster(CTFTermNum)(SurfNum) = SurfInitialTemp; - state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) = SurfInitialTemp; - state.dataHeatBalSurf->SurfInsideFluxHistMaster(CTFTermNum)(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfOutsideFluxHistMaster(CTFTermNum)(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) = 0; + } + for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) { + for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) { + state.dataHeatBalSurf->SurfInsideTempHistMaster(CTFTermNum)(SurfNum) = SurfInitialTemp; + state.dataHeatBalSurf->SurfOutsideTempHistMaster(CTFTermNum)(SurfNum) = SurfInitialTemp; + state.dataHeatBalSurf->SurfInsideFluxHistMaster(CTFTermNum)(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfOutsideFluxHistMaster(CTFTermNum)(SurfNum) = 0.0; + } } } } } if (state.dataHeatBal->AnyInternalHeatSourceInInput) { for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurf = state.dataHeatBal->Zone(zoneNum).HTSurfaceFirst; - int const lastSurf = state.dataHeatBal->Zone(zoneNum).HTSurfaceLast; - for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) { - for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) { - state.dataHeatBalSurf->SurfTsrcHist(SurfNum, CTFTermNum) = SurfInitialTemp; - state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, CTFTermNum) = SurfInitialTemp; - state.dataHeatBalSurf->SurfTuserHist(SurfNum, CTFTermNum) = SurfInitialTemp; - state.dataHeatBalSurf->SurfTuserHistM(SurfNum, CTFTermNum) = SurfInitialTemp; - state.dataHeatBalSurf->SurfQsrcHist(SurfNum, CTFTermNum) = 0.0; - state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, CTFTermNum) = 0.0; + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurf = thisSpace.HTSurfaceFirst; + int const lastSurf = thisSpace.HTSurfaceLast; + for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) { + for (int CTFTermNum = 1; CTFTermNum <= Construction::MaxCTFTerms; ++CTFTermNum) { + state.dataHeatBalSurf->SurfTsrcHist(SurfNum, CTFTermNum) = SurfInitialTemp; + state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, CTFTermNum) = SurfInitialTemp; + state.dataHeatBalSurf->SurfTuserHist(SurfNum, CTFTermNum) = SurfInitialTemp; + state.dataHeatBalSurf->SurfTuserHistM(SurfNum, CTFTermNum) = SurfInitialTemp; + state.dataHeatBalSurf->SurfQsrcHist(SurfNum, CTFTermNum) = 0.0; + state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, CTFTermNum) = 0.0; + } } } } @@ -2446,59 +2448,62 @@ void InitSolarHeatGains(EnergyPlusData &state) state.dataHeatBal->EnclSolInitialDifSolReflW(enclNum) = 0.0; } for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurfOpaq = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceFirst; - int const lastSurfOpaq = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceLast; - for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) { - state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) = 0.0; - state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(SurfNum) = 0.0; - state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(SurfNum) = 0.0; - } - - int const firstSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceFirst; - int const lastSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceLast; - for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { - // Faster "inline" than calling SurfaceWindow( SurfNum ).InitSolarHeatGains() - state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) = 0.0; - state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) = 0.0; - state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) = 0.0; - state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) = 0.0; - state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) = 0.0; - state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = 0.0; - state.dataSurface->SurfWinConvHeatFlowNatural(SurfNum) = 0.0; - state.dataSurface->SurfWinConvHeatGainToZoneAir(SurfNum) = 0.0; - state.dataSurface->SurfWinRetHeatGainToZoneAir(SurfNum) = 0.0; - state.dataSurface->SurfWinDividerHeatGain(SurfNum) = 0.0; - } - - for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { - state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) = 0.0; - state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) = 0.0; - state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) = 0.0; - state.dataSurface->SurfWinGainFrameDividerToZoneRep(SurfNum) = 0.0; - state.dataSurface->SurfWinGainConvShadeToZoneRep(SurfNum) = 0.0; - state.dataSurface->SurfWinGainIRShadeToZoneRep(SurfNum) = 0.0; - state.dataSurface->SurfWinGapConvHtFlowRep(SurfNum) = 0.0; - state.dataSurface->SurfWinShadingAbsorbedSolar(SurfNum) = 0.0; - state.dataSurface->SurfWinSysSolTransmittance(SurfNum) = 0.0; - } - for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { - state.dataSurface->SurfWinHeatGain(SurfNum) = 0.0; - state.dataSurface->SurfWinHeatGainRep(SurfNum) = 0.0; - state.dataSurface->SurfWinHeatLossRep(SurfNum) = 0.0; - state.dataSurface->SurfWinHeatGainRepEnergy(SurfNum) = 0.0; - state.dataSurface->SurfWinHeatLossRepEnergy(SurfNum) = 0.0; - state.dataSurface->SurfWinGapConvHtFlowRepEnergy(SurfNum) = 0.0; - state.dataSurface->SurfWinShadingAbsorbedSolarEnergy(SurfNum) = 0.0; - } - for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL + 1; Lay++) { + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst; + int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast; + for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) { + state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) = 0.0; + state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(SurfNum) = 0.0; + state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(SurfNum) = 0.0; + } + + int const firstSurfWin = thisSpace.WindowSurfaceFirst; + int const lastSurfWin = thisSpace.WindowSurfaceLast; + for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { + // Faster "inline" than calling SurfaceWindow( SurfNum ).InitSolarHeatGains() + state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) = 0.0; + state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) = 0.0; + state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) = 0.0; + state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) = 0.0; + state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) = 0.0; + state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = 0.0; + state.dataSurface->SurfWinConvHeatFlowNatural(SurfNum) = 0.0; + state.dataSurface->SurfWinConvHeatGainToZoneAir(SurfNum) = 0.0; + state.dataSurface->SurfWinRetHeatGainToZoneAir(SurfNum) = 0.0; + state.dataSurface->SurfWinDividerHeatGain(SurfNum) = 0.0; + } + + for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { + state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) = 0.0; + state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) = 0.0; + state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) = 0.0; + state.dataSurface->SurfWinGainFrameDividerToZoneRep(SurfNum) = 0.0; + state.dataSurface->SurfWinGainConvShadeToZoneRep(SurfNum) = 0.0; + state.dataSurface->SurfWinGainIRShadeToZoneRep(SurfNum) = 0.0; + state.dataSurface->SurfWinGapConvHtFlowRep(SurfNum) = 0.0; + state.dataSurface->SurfWinShadingAbsorbedSolar(SurfNum) = 0.0; + state.dataSurface->SurfWinSysSolTransmittance(SurfNum) = 0.0; + } for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { - state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = 0.0; + state.dataSurface->SurfWinHeatGain(SurfNum) = 0.0; + state.dataSurface->SurfWinHeatGainRep(SurfNum) = 0.0; + state.dataSurface->SurfWinHeatLossRep(SurfNum) = 0.0; + state.dataSurface->SurfWinHeatGainRepEnergy(SurfNum) = 0.0; + state.dataSurface->SurfWinHeatLossRepEnergy(SurfNum) = 0.0; + state.dataSurface->SurfWinGapConvHtFlowRepEnergy(SurfNum) = 0.0; + state.dataSurface->SurfWinShadingAbsorbedSolarEnergy(SurfNum) = 0.0; + } + for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL + 1; Lay++) { + for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = 0.0; + } } } } @@ -2551,80 +2556,83 @@ void InitSolarHeatGains(EnergyPlusData &state) state.dataHeatBal->ZoneDifSolFrIntWinsRepEnergy(enclNum) = 0.0; } for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceFirst; - int const lastSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceLast; - for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { - state.dataSurface->SurfWinExtBeamAbsByShade(SurfNum) = 0.0; - state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = 0.0; - state.dataSurface->SurfWinIntBeamAbsByShade(SurfNum) = 0.0; - state.dataSurface->SurfWinInitialDifSolAbsByShade(SurfNum) = 0.0; - state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0; - state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) = 0.0; - state.dataHeatBal->SurfWinSWwinAbsTotalReport(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(SurfNum) = 0.0; - state.dataHeatBal->SurfWinInitialDifSolInTransReport(SurfNum) = 0.0; - } - for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { - state.dataSurface->SurfWinBlTsolBmBm(SurfNum) = 0.0; - state.dataSurface->SurfWinBlTsolBmDif(SurfNum) = 0.0; - state.dataSurface->SurfWinBlTsolDifDif(SurfNum) = 0.0; - state.dataSurface->SurfWinBlGlSysTsolBmBm(SurfNum) = 0.0; - state.dataSurface->SurfWinBlGlSysTsolDifDif(SurfNum) = 0.0; - state.dataSurface->SurfWinScTsolBmBm(SurfNum) = 0.0; - state.dataSurface->SurfWinScTsolBmDif(SurfNum) = 0.0; - state.dataSurface->SurfWinScTsolDifDif(SurfNum) = 0.0; - state.dataSurface->SurfWinScGlSysTsolBmBm(SurfNum) = 0.0; - state.dataSurface->SurfWinScGlSysTsolDifDif(SurfNum) = 0.0; - state.dataSurface->SurfWinGlTsolBmBm(SurfNum) = 0.0; - state.dataSurface->SurfWinGlTsolBmDif(SurfNum) = 0.0; - state.dataSurface->SurfWinGlTsolDifDif(SurfNum) = 0.0; - } - for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { - state.dataSurface->SurfWinBmSolTransThruIntWinRep(SurfNum) = 0.0; - state.dataSurface->SurfWinBmSolAbsdOutsReveal(SurfNum) = 0.0; - state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) = 0.0; - state.dataSurface->SurfWinBmSolRefldInsReveal(SurfNum) = 0.0; - state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) = 0.0; - state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum) = 0.0; - state.dataSurface->SurfWinInsRevealDiffIntoZone(SurfNum) = 0.0; - state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) = 0.0; - state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) = 0.0; - } - for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { - state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfNum) = 0.0; - state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfNum) = 0.0; - state.dataSurface->SurfWinBmSolAbsdInsRevealReport(SurfNum) = 0.0; - state.dataSurface->SurfWinInsRevealDiffOntoGlazingReport(SurfNum) = 0.0; - state.dataSurface->SurfWinInsRevealDiffIntoZoneReport(SurfNum) = 0.0; - state.dataSurface->SurfWinInsRevealDiffOntoFrameReport(SurfNum) = 0.0; - state.dataSurface->SurfWinBmSolTransThruIntWinRepEnergy(SurfNum) = 0.0; - state.dataSurface->SurfWinBmSolRefldOutsRevealRepEnergy(SurfNum) = 0.0; - state.dataSurface->SurfWinBmSolRefldInsRevealRepEnergy(SurfNum) = 0.0; - } - - for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { - state.dataSurface->SurfWinTransSolar(SurfNum) = 0.0; - state.dataSurface->SurfWinBmSolar(SurfNum) = 0.0; - state.dataSurface->SurfWinBmBmSolar(SurfNum) = 0.0; - state.dataSurface->SurfWinBmDifSolar(SurfNum) = 0.0; - state.dataSurface->SurfWinDifSolar(SurfNum) = 0.0; - state.dataSurface->SurfWinTransSolarEnergy(SurfNum) = 0.0; - state.dataSurface->SurfWinBmSolarEnergy(SurfNum) = 0.0; - state.dataSurface->SurfWinBmBmSolarEnergy(SurfNum) = 0.0; - state.dataSurface->SurfWinBmDifSolarEnergy(SurfNum) = 0.0; - state.dataSurface->SurfWinDifSolarEnergy(SurfNum) = 0.0; - state.dataHeatBal->SurfWinBSDFBeamDirectionRep(SurfNum) = 0; - state.dataHeatBal->SurfWinBSDFBeamThetaRep(SurfNum) = 0.0; - state.dataHeatBal->SurfWinBSDFBeamPhiRep(SurfNum) = 0.0; - } - for (int Lay = 1; Lay <= state.dataHeatBal->MaxSolidWinLayers; Lay++) { + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurfWin = thisSpace.WindowSurfaceFirst; + int const lastSurfWin = thisSpace.WindowSurfaceLast; for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { - state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) = 0.0; + state.dataSurface->SurfWinExtBeamAbsByShade(SurfNum) = 0.0; + state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = 0.0; + state.dataSurface->SurfWinIntBeamAbsByShade(SurfNum) = 0.0; + state.dataSurface->SurfWinInitialDifSolAbsByShade(SurfNum) = 0.0; + state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0; + state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) = 0.0; + state.dataHeatBal->SurfWinSWwinAbsTotalReport(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(SurfNum) = 0.0; + state.dataHeatBal->SurfWinInitialDifSolInTransReport(SurfNum) = 0.0; } - } - for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL; Lay++) { for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { - state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, Lay) = 0.0; + state.dataSurface->SurfWinBlTsolBmBm(SurfNum) = 0.0; + state.dataSurface->SurfWinBlTsolBmDif(SurfNum) = 0.0; + state.dataSurface->SurfWinBlTsolDifDif(SurfNum) = 0.0; + state.dataSurface->SurfWinBlGlSysTsolBmBm(SurfNum) = 0.0; + state.dataSurface->SurfWinBlGlSysTsolDifDif(SurfNum) = 0.0; + state.dataSurface->SurfWinScTsolBmBm(SurfNum) = 0.0; + state.dataSurface->SurfWinScTsolBmDif(SurfNum) = 0.0; + state.dataSurface->SurfWinScTsolDifDif(SurfNum) = 0.0; + state.dataSurface->SurfWinScGlSysTsolBmBm(SurfNum) = 0.0; + state.dataSurface->SurfWinScGlSysTsolDifDif(SurfNum) = 0.0; + state.dataSurface->SurfWinGlTsolBmBm(SurfNum) = 0.0; + state.dataSurface->SurfWinGlTsolBmDif(SurfNum) = 0.0; + state.dataSurface->SurfWinGlTsolDifDif(SurfNum) = 0.0; + } + for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { + state.dataSurface->SurfWinBmSolTransThruIntWinRep(SurfNum) = 0.0; + state.dataSurface->SurfWinBmSolAbsdOutsReveal(SurfNum) = 0.0; + state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) = 0.0; + state.dataSurface->SurfWinBmSolRefldInsReveal(SurfNum) = 0.0; + state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) = 0.0; + state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum) = 0.0; + state.dataSurface->SurfWinInsRevealDiffIntoZone(SurfNum) = 0.0; + state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) = 0.0; + state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) = 0.0; + } + for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { + state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfNum) = 0.0; + state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfNum) = 0.0; + state.dataSurface->SurfWinBmSolAbsdInsRevealReport(SurfNum) = 0.0; + state.dataSurface->SurfWinInsRevealDiffOntoGlazingReport(SurfNum) = 0.0; + state.dataSurface->SurfWinInsRevealDiffIntoZoneReport(SurfNum) = 0.0; + state.dataSurface->SurfWinInsRevealDiffOntoFrameReport(SurfNum) = 0.0; + state.dataSurface->SurfWinBmSolTransThruIntWinRepEnergy(SurfNum) = 0.0; + state.dataSurface->SurfWinBmSolRefldOutsRevealRepEnergy(SurfNum) = 0.0; + state.dataSurface->SurfWinBmSolRefldInsRevealRepEnergy(SurfNum) = 0.0; + } + + for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { + state.dataSurface->SurfWinTransSolar(SurfNum) = 0.0; + state.dataSurface->SurfWinBmSolar(SurfNum) = 0.0; + state.dataSurface->SurfWinBmBmSolar(SurfNum) = 0.0; + state.dataSurface->SurfWinBmDifSolar(SurfNum) = 0.0; + state.dataSurface->SurfWinDifSolar(SurfNum) = 0.0; + state.dataSurface->SurfWinTransSolarEnergy(SurfNum) = 0.0; + state.dataSurface->SurfWinBmSolarEnergy(SurfNum) = 0.0; + state.dataSurface->SurfWinBmBmSolarEnergy(SurfNum) = 0.0; + state.dataSurface->SurfWinBmDifSolarEnergy(SurfNum) = 0.0; + state.dataSurface->SurfWinDifSolarEnergy(SurfNum) = 0.0; + state.dataHeatBal->SurfWinBSDFBeamDirectionRep(SurfNum) = 0; + state.dataHeatBal->SurfWinBSDFBeamThetaRep(SurfNum) = 0.0; + state.dataHeatBal->SurfWinBSDFBeamPhiRep(SurfNum) = 0.0; + } + for (int Lay = 1; Lay <= state.dataHeatBal->MaxSolidWinLayers; Lay++) { + for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { + state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) = 0.0; + } + } + for (int Lay = 1; Lay <= DataWindowEquivalentLayer::CFSMAXNL; Lay++) { + for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { + state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, Lay) = 0.0; + } } } } @@ -2987,546 +2995,560 @@ void InitSolarHeatGains(EnergyPlusData &state) // Calculate Exterior and Interior Absorbed Short Wave Radiation for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurfOpaq = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceFirst; - int const lastSurfOpaq = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceLast; - for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) { - int const ConstrNum = state.dataSurface->Surface(SurfNum).Construction; - Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier; - currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier; - if (Surface(SurfNum).ExtSolar) { - Real64 AbsExt = - state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum); // Absorptivity of outer most layer (or movable insulation if present) - state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) = - state.dataSurface->SurfOpaqAO(SurfNum) * currBeamSolar(SurfNum) + - AbsExt * (state.dataSurface->SurfSkySolarInc(SurfNum) + state.dataSurface->SurfGndSolarInc(SurfNum)); - } - if (ConstrNum > 0) { - int SurfSolIncPtr = SurfaceScheduledSolarInc(state, SurfNum, ConstrNum); - if (SurfSolIncPtr == 0) { - if (state.dataConstruction->Construct(ConstrNum).TransDiff <= 0.0) { // Opaque surface - int ShelfNum = state.dataSurface->SurfDaylightingShelfInd(SurfNum); // Daylighting shelf object number - int InShelfSurf = 0; // Inside daylighting shelf surface number - if (ShelfNum > 0) { - InShelfSurf = state.dataDaylightingDevicesData->Shelf(ShelfNum).InSurf; // Inside daylighting shelf present if > 0 - } - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum); - if (InShelfSurf > 0) { // Inside daylighting shelf - // Shelf surface area is divided by 2 because only one side sees beam (Area was multiplied by 2 during init) - state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) = - state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum) * (0.5 * Surface(SurfNum).Area); - } else { // Regular surface - state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) = - state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum) * Surface(SurfNum).Area; + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst; + int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast; + for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) { + int const ConstrNum = state.dataSurface->Surface(SurfNum).Construction; + Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier; + currBeamSolar(SurfNum) = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier; + if (Surface(SurfNum).ExtSolar) { + Real64 AbsExt = + state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum); // Absorptivity of outer most layer (or movable insulation if present) + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) = + state.dataSurface->SurfOpaqAO(SurfNum) * currBeamSolar(SurfNum) + + AbsExt * (state.dataSurface->SurfSkySolarInc(SurfNum) + state.dataSurface->SurfGndSolarInc(SurfNum)); + } + if (ConstrNum > 0) { + int SurfSolIncPtr = SurfaceScheduledSolarInc(state, SurfNum, ConstrNum); + if (SurfSolIncPtr == 0) { + if (state.dataConstruction->Construct(ConstrNum).TransDiff <= 0.0) { // Opaque surface + int ShelfNum = state.dataSurface->SurfDaylightingShelfInd(SurfNum); // Daylighting shelf object number + int InShelfSurf = 0; // Inside daylighting shelf surface number + if (ShelfNum > 0) { + InShelfSurf = state.dataDaylightingDevicesData->Shelf(ShelfNum).InSurf; // Inside daylighting shelf present if > 0 + } + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += + state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum); + if (InShelfSurf > 0) { // Inside daylighting shelf + // Shelf surface area is divided by 2 because only one side sees beam (Area was multiplied by 2 during init) + state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) = + state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum) * (0.5 * Surface(SurfNum).Area); + } else { // Regular surface + state.dataHeatBalSurf->SurfOpaqInsFaceBeamSolAbsorbed(SurfNum) = + state.dataSurface->SurfOpaqAI(SurfNum) * currBeamSolar(SurfNum) * Surface(SurfNum).Area; + } } + } else { + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataSurface->SurfOpaqAI(SurfNum); } - } else { - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataSurface->SurfOpaqAI(SurfNum); } } - } - int const firstSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceFirst; - int const lastSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceLast; - for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { - if (Surface(SurfNum).ExtSolar || state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::TDD_Diffuser) { - // Exclude special shading surfaces which required SurfOpaqQRadSWOut calculations above - int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); - Real64 CosInc = state.dataHeatBal->SurfCosIncidenceAngle(SurfNum); // Cosine of incidence angle of beam solar on glass - Real64 BeamSolar = currBeamSolar(SurfNum); // Local variable for BeamSolarRad - Real64 SkySolarInc = state.dataSurface->SurfSkySolarInc(SurfNum); // Sky diffuse solar incident on a surface - Real64 GndSolarInc = state.dataSurface->SurfGndSolarInc(SurfNum); // Ground diffuse solar incident on a surface - - WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum); - - if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::Detailed && - !state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) { - int TotGlassLay = state.dataConstruction->Construct(ConstrNum).TotGlassLayers; // Number of glass layers - for (int Lay = 1; Lay <= TotGlassLay; ++Lay) { - AbsDiffWin(Lay) = state.dataConstruction->Construct(ConstrNum).AbsDiff(Lay); - } + int const firstSurfWin = thisSpace.WindowSurfaceFirst; + int const lastSurfWin = thisSpace.WindowSurfaceLast; + for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { + if (Surface(SurfNum).ExtSolar || state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::TDD_Diffuser) { + // Exclude special shading surfaces which required SurfOpaqQRadSWOut calculations above + int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); + Real64 CosInc = state.dataHeatBal->SurfCosIncidenceAngle(SurfNum); // Cosine of incidence angle of beam solar on glass + Real64 BeamSolar = currBeamSolar(SurfNum); // Local variable for BeamSolarRad + Real64 SkySolarInc = state.dataSurface->SurfSkySolarInc(SurfNum); // Sky diffuse solar incident on a surface + Real64 GndSolarInc = state.dataSurface->SurfGndSolarInc(SurfNum); // Ground diffuse solar incident on a surface + + WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum); + + if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::Detailed && + !state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) { + int TotGlassLay = state.dataConstruction->Construct(ConstrNum).TotGlassLayers; // Number of glass layers + for (int Lay = 1; Lay <= TotGlassLay; ++Lay) { + AbsDiffWin(Lay) = state.dataConstruction->Construct(ConstrNum).AbsDiff(Lay); + } - if (IS_SHADED(ShadeFlag)) { // Shaded window + if (IS_SHADED(ShadeFlag)) { // Shaded window - int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum); // Shaded window construction + int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum); // Shaded window construction - if (ANY_SHADE_SCREEN(ShadeFlag)) { // Shade/screen on - for (int Lay = 1; Lay <= TotGlassLay; ++Lay) { - AbsDiffWin(Lay) = state.dataConstruction->Construct(ConstrNumSh).AbsDiff(Lay); - } - state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = - state.dataConstruction->Construct(ConstrNumSh).AbsDiffShade * (SkySolarInc + GndSolarInc); - } else if (ANY_BLIND(ShadeFlag)) { // Blind on - int SurfWinSlatsAngIndex = state.dataSurface->SurfWinSlatsAngIndex(SurfNum); - Real64 SurfWinSlatsAngInterpFac = state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum); - Real64 AbsDiffBlind; - if (state.dataSurface->SurfWinMovableSlats(SurfNum)) { - for (int Lay = 1; Lay <= TotGlassLay; ++Lay) { - AbsDiffWin(Lay) = General::InterpGeneral( - state.dataConstruction->Construct(ConstrNumSh).BlAbsDiff(SurfWinSlatsAngIndex, Lay), - state.dataConstruction->Construct(ConstrNumSh) - .BlAbsDiff(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1), Lay), - SurfWinSlatsAngInterpFac); - AbsDiffWinGnd(Lay) = General::InterpGeneral( - state.dataConstruction->Construct(ConstrNumSh).BlAbsDiffGnd(SurfWinSlatsAngIndex, Lay), - state.dataConstruction->Construct(ConstrNumSh) - .BlAbsDiffGnd(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1), Lay), - SurfWinSlatsAngInterpFac); - AbsDiffWinSky(Lay) = General::InterpGeneral( - state.dataConstruction->Construct(ConstrNumSh).BlAbsDiffSky(SurfWinSlatsAngIndex, Lay), - state.dataConstruction->Construct(ConstrNumSh) - .BlAbsDiffSky(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1), Lay), - SurfWinSlatsAngInterpFac); - } - AbsDiffBlind = General::InterpGeneral( - state.dataConstruction->Construct(ConstrNumSh).AbsDiffBlind(SurfWinSlatsAngIndex), - state.dataConstruction->Construct(ConstrNumSh).AbsDiffBlind(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)), - SurfWinSlatsAngInterpFac); - } else { + if (ANY_SHADE_SCREEN(ShadeFlag)) { // Shade/screen on for (int Lay = 1; Lay <= TotGlassLay; ++Lay) { - AbsDiffWin(Lay) = state.dataConstruction->Construct(ConstrNumSh).BlAbsDiff(1, Lay); - AbsDiffWinGnd(Lay) = state.dataConstruction->Construct(ConstrNumSh).BlAbsDiffGnd(1, Lay); - AbsDiffWinSky(Lay) = state.dataConstruction->Construct(ConstrNumSh).BlAbsDiffSky(1, Lay); + AbsDiffWin(Lay) = state.dataConstruction->Construct(ConstrNumSh).AbsDiff(Lay); } - AbsDiffBlind = state.dataConstruction->Construct(ConstrNumSh).AbsDiffBlind(1); - } - state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = AbsDiffBlind * (SkySolarInc + GndSolarInc); - - if (state.dataHeatBal->Blind(state.dataSurface->SurfWinBlindNumber(SurfNum)).SlatOrientation == - DataWindowEquivalentLayer::Orientation::Horizontal) { - Real64 ACosTlt = std::abs(Surface(SurfNum).CosTilt); - Real64 AbsDiffBlindGnd; - Real64 AbsDiffBlindSky; + state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = + state.dataConstruction->Construct(ConstrNumSh).AbsDiffShade * (SkySolarInc + GndSolarInc); + } else if (ANY_BLIND(ShadeFlag)) { // Blind on + int SurfWinSlatsAngIndex = state.dataSurface->SurfWinSlatsAngIndex(SurfNum); + Real64 SurfWinSlatsAngInterpFac = state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum); + Real64 AbsDiffBlind; if (state.dataSurface->SurfWinMovableSlats(SurfNum)) { - AbsDiffBlindGnd = General::InterpGeneral( - state.dataConstruction->Construct(ConstrNumSh).AbsDiffBlindGnd(SurfWinSlatsAngIndex), - state.dataConstruction->Construct(ConstrNumSh) - .AbsDiffBlindGnd(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)), - SurfWinSlatsAngInterpFac); - AbsDiffBlindSky = General::InterpGeneral( - state.dataConstruction->Construct(ConstrNumSh).AbsDiffBlindSky(SurfWinSlatsAngIndex), - state.dataConstruction->Construct(ConstrNumSh) - .AbsDiffBlindSky(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)), - SurfWinSlatsAngInterpFac); + for (int Lay = 1; Lay <= TotGlassLay; ++Lay) { + AbsDiffWin(Lay) = General::InterpGeneral( + state.dataConstruction->Construct(ConstrNumSh).BlAbsDiff(SurfWinSlatsAngIndex, Lay), + state.dataConstruction->Construct(ConstrNumSh) + .BlAbsDiff(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1), Lay), + SurfWinSlatsAngInterpFac); + AbsDiffWinGnd(Lay) = General::InterpGeneral( + state.dataConstruction->Construct(ConstrNumSh).BlAbsDiffGnd(SurfWinSlatsAngIndex, Lay), + state.dataConstruction->Construct(ConstrNumSh) + .BlAbsDiffGnd(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1), Lay), + SurfWinSlatsAngInterpFac); + AbsDiffWinSky(Lay) = General::InterpGeneral( + state.dataConstruction->Construct(ConstrNumSh).BlAbsDiffSky(SurfWinSlatsAngIndex, Lay), + state.dataConstruction->Construct(ConstrNumSh) + .BlAbsDiffSky(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1), Lay), + SurfWinSlatsAngInterpFac); + } + AbsDiffBlind = + General::InterpGeneral(state.dataConstruction->Construct(ConstrNumSh).AbsDiffBlind(SurfWinSlatsAngIndex), + state.dataConstruction->Construct(ConstrNumSh) + .AbsDiffBlind(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)), + SurfWinSlatsAngInterpFac); } else { - AbsDiffBlindGnd = state.dataConstruction->Construct(ConstrNumSh).AbsDiffBlindGnd(1); - AbsDiffBlindSky = state.dataConstruction->Construct(ConstrNumSh).AbsDiffBlindSky(1); + for (int Lay = 1; Lay <= TotGlassLay; ++Lay) { + AbsDiffWin(Lay) = state.dataConstruction->Construct(ConstrNumSh).BlAbsDiff(1, Lay); + AbsDiffWinGnd(Lay) = state.dataConstruction->Construct(ConstrNumSh).BlAbsDiffGnd(1, Lay); + AbsDiffWinSky(Lay) = state.dataConstruction->Construct(ConstrNumSh).BlAbsDiffSky(1, Lay); + } + AbsDiffBlind = state.dataConstruction->Construct(ConstrNumSh).AbsDiffBlind(1); + } + state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = AbsDiffBlind * (SkySolarInc + GndSolarInc); + + if (state.dataHeatBal->Blind(state.dataSurface->SurfWinBlindNumber(SurfNum)).SlatOrientation == + DataWindowEquivalentLayer::Orientation::Horizontal) { + Real64 ACosTlt = std::abs(Surface(SurfNum).CosTilt); + Real64 AbsDiffBlindGnd; + Real64 AbsDiffBlindSky; + if (state.dataSurface->SurfWinMovableSlats(SurfNum)) { + AbsDiffBlindGnd = General::InterpGeneral( + state.dataConstruction->Construct(ConstrNumSh).AbsDiffBlindGnd(SurfWinSlatsAngIndex), + state.dataConstruction->Construct(ConstrNumSh) + .AbsDiffBlindGnd(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)), + SurfWinSlatsAngInterpFac); + AbsDiffBlindSky = General::InterpGeneral( + state.dataConstruction->Construct(ConstrNumSh).AbsDiffBlindSky(SurfWinSlatsAngIndex), + state.dataConstruction->Construct(ConstrNumSh) + .AbsDiffBlindSky(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)), + SurfWinSlatsAngInterpFac); + } else { + AbsDiffBlindGnd = state.dataConstruction->Construct(ConstrNumSh).AbsDiffBlindGnd(1); + AbsDiffBlindSky = state.dataConstruction->Construct(ConstrNumSh).AbsDiffBlindSky(1); + } + state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = + SkySolarInc * (0.5 * ACosTlt * AbsDiffBlindGnd + (1.0 - 0.5 * ACosTlt) * AbsDiffBlindSky) + + GndSolarInc * ((1.0 - 0.5 * ACosTlt) * AbsDiffBlindGnd + 0.5 * ACosTlt * AbsDiffBlindSky); } - state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) = - SkySolarInc * (0.5 * ACosTlt * AbsDiffBlindGnd + (1.0 - 0.5 * ACosTlt) * AbsDiffBlindSky) + - GndSolarInc * ((1.0 - 0.5 * ACosTlt) * AbsDiffBlindGnd + 0.5 * ACosTlt * AbsDiffBlindSky); } - } - // Correct for shadowing of divider onto interior shading device (note that dividers are - // not allowed in windows with between-glass shade/blind) + // Correct for shadowing of divider onto interior shading device (note that dividers are + // not allowed in windows with between-glass shade/blind) - if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag) && state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) - state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) *= state.dataSurface->SurfWinGlazedFrac(SurfNum); + if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag) && state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) + state.dataSurface->SurfWinExtDiffAbsByShade(SurfNum) *= state.dataSurface->SurfWinGlazedFrac(SurfNum); - if (ShadeFlag == WinShadingType::SwitchableGlazing) { // Switchable glazing - Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum); // Switching factor for switchable glazing - for (int Lay = 1; Lay <= TotGlassLay; ++Lay) { - AbsDiffWin(Lay) = - InterpSw(SwitchFac, AbsDiffWin(Lay), state.dataConstruction->Construct(ConstrNumSh).AbsDiff(Lay)); + if (ShadeFlag == WinShadingType::SwitchableGlazing) { // Switchable glazing + Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum); // Switching factor for switchable glazing + for (int Lay = 1; Lay <= TotGlassLay; ++Lay) { + AbsDiffWin(Lay) = + InterpSw(SwitchFac, AbsDiffWin(Lay), state.dataConstruction->Construct(ConstrNumSh).AbsDiff(Lay)); + } } - } - } // End of check if window has shading device on - - state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0; - for (int Lay = 1; Lay <= TotGlassLay; ++Lay) { - state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = - AbsDiffWin(Lay) * (SkySolarInc + GndSolarInc) + state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar; - // SurfWinA is from InteriorSolarDistribution - if (ANY_BLIND(ShadeFlag)) { - int ConstrNumSh = Surface(SurfNum).activeShadedConstruction; - if (state.dataHeatBal->Blind(state.dataSurface->SurfWinBlindNumber(SurfNum)).SlatOrientation == - DataWindowEquivalentLayer::Orientation::Horizontal) { - Real64 ACosTlt = std::abs(Surface(SurfNum).CosTilt); // Absolute value of cosine of surface tilt angle - Real64 AbsDiffGlassLayGnd; // System glass layer ground diffuse solar absorptance with blind on - Real64 AbsDiffGlassLaySky; // System glass layer sky diffuse solar absorptance with blind on - if (state.dataSurface->SurfWinMovableSlats(SurfNum)) { - AbsDiffGlassLayGnd = General::InterpGeneral( - state.dataConstruction->Construct(ConstrNumSh) - .BlAbsDiffGnd(state.dataSurface->SurfWinSlatsAngIndex(SurfNum), Lay), - state.dataConstruction->Construct(ConstrNumSh) - .BlAbsDiffGnd(std::min(MaxSlatAngs, state.dataSurface->SurfWinSlatsAngIndex(SurfNum) + 1), Lay), - state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum)); - AbsDiffGlassLaySky = General::InterpGeneral( - state.dataConstruction->Construct(ConstrNumSh) - .BlAbsDiffSky(state.dataSurface->SurfWinSlatsAngIndex(SurfNum), Lay), - state.dataConstruction->Construct(ConstrNumSh) - .BlAbsDiffSky(std::min(MaxSlatAngs, state.dataSurface->SurfWinSlatsAngIndex(SurfNum) + 1), Lay), - state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum)); - } else { - AbsDiffGlassLayGnd = state.dataConstruction->Construct(ConstrNumSh).BlAbsDiffGnd(1, Lay); - AbsDiffGlassLaySky = state.dataConstruction->Construct(ConstrNumSh).BlAbsDiffSky(1, Lay); + } // End of check if window has shading device on + + state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0; + for (int Lay = 1; Lay <= TotGlassLay; ++Lay) { + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = + AbsDiffWin(Lay) * (SkySolarInc + GndSolarInc) + state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar; + // SurfWinA is from InteriorSolarDistribution + if (ANY_BLIND(ShadeFlag)) { + int ConstrNumSh = Surface(SurfNum).activeShadedConstruction; + if (state.dataHeatBal->Blind(state.dataSurface->SurfWinBlindNumber(SurfNum)).SlatOrientation == + DataWindowEquivalentLayer::Orientation::Horizontal) { + Real64 ACosTlt = std::abs(Surface(SurfNum).CosTilt); // Absolute value of cosine of surface tilt angle + Real64 AbsDiffGlassLayGnd; // System glass layer ground diffuse solar absorptance with blind on + Real64 AbsDiffGlassLaySky; // System glass layer sky diffuse solar absorptance with blind on + if (state.dataSurface->SurfWinMovableSlats(SurfNum)) { + AbsDiffGlassLayGnd = General::InterpGeneral( + state.dataConstruction->Construct(ConstrNumSh) + .BlAbsDiffGnd(state.dataSurface->SurfWinSlatsAngIndex(SurfNum), Lay), + state.dataConstruction->Construct(ConstrNumSh) + .BlAbsDiffGnd(std::min(MaxSlatAngs, state.dataSurface->SurfWinSlatsAngIndex(SurfNum) + 1), Lay), + state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum)); + AbsDiffGlassLaySky = General::InterpGeneral( + state.dataConstruction->Construct(ConstrNumSh) + .BlAbsDiffSky(state.dataSurface->SurfWinSlatsAngIndex(SurfNum), Lay), + state.dataConstruction->Construct(ConstrNumSh) + .BlAbsDiffSky(std::min(MaxSlatAngs, state.dataSurface->SurfWinSlatsAngIndex(SurfNum) + 1), Lay), + state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum)); + } else { + AbsDiffGlassLayGnd = state.dataConstruction->Construct(ConstrNumSh).BlAbsDiffGnd(1, Lay); + AbsDiffGlassLaySky = state.dataConstruction->Construct(ConstrNumSh).BlAbsDiffSky(1, Lay); + } + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = + SkySolarInc * (0.5 * ACosTlt * AbsDiffGlassLayGnd + (1.0 - 0.5 * ACosTlt) * AbsDiffGlassLaySky) + + GndSolarInc * ((1.0 - 0.5 * ACosTlt) * AbsDiffGlassLayGnd + 0.5 * ACosTlt * AbsDiffGlassLaySky) + + state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar; } - state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = - SkySolarInc * (0.5 * ACosTlt * AbsDiffGlassLayGnd + (1.0 - 0.5 * ACosTlt) * AbsDiffGlassLaySky) + - GndSolarInc * ((1.0 - 0.5 * ACosTlt) * AbsDiffGlassLayGnd + 0.5 * ACosTlt * AbsDiffGlassLaySky) + - state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar; } + // Total solar absorbed in solid layer (W), for reporting + state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) = + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area; + + // Total solar absorbed in all glass layers (W), for reporting + state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay); } - // Total solar absorbed in solid layer (W), for reporting - state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) = - state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area; + state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) = + state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec; + // Need to do it this way for now beaucse of scheduled surface gains. They do work only with + // BSDF windows and overwriting absorbtances will work only for ordinary windows + // } else if ( SurfaceWindow( SurfNum ).WindowModelType != WindowModel:: BSDF && + // SurfaceWindow( SurfNum ).WindowModelType != WindowModel:: EQL && + // inExtWindowModel->isExternalLibraryModel() ) { + // TotSolidLay = Construct( ConstrNum ).TotSolidLayers; + // for ( Lay = 1; Lay <= TotSolidLay; ++Lay ) { + // SurfWinQRadSWwinAbs( Lay, SurfNum ) = SurfWinA( Lay, SurfNum ) * + // ( SurfQRadSWOutIncident( SurfNum ) + QS( Surface( SurfNum ).Zone ) ); + // } + } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) { + int TotSolidLay = state.dataConstruction->Construct(ConstrNum).TotSolidLayers; + // Number of solid layers in fenestration system (glass + shading) + int CurrentState = state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState; + // Current state for Complex Fenestration + // Examine for schedule surface gain + Real64 SurfSolAbs = + WindowScheduledSolarAbs(state, + SurfNum, + ConstrNum); // Pointer to scheduled surface gains object for fenestration systems + + for (int Lay = 1; Lay <= TotSolidLay; ++Lay) { + if (SurfSolAbs != 0) { + state.dataSurface->SurfWinA(SurfNum, Lay) = + GetCurrentScheduleValue(state, state.dataSurface->FenLayAbsSSG(SurfSolAbs).SchedPtrs(Lay)); + // ABWin(Lay) = SurfWinA(SurfNum,Lay) + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = state.dataSurface->SurfWinA(SurfNum, Lay); + } else { + // Several notes about this equation. First part is accounting for duffuse solar radiation for the ground + // and from the sky. Second item (SurfWinA(SurfNum,Lay) * BeamSolar) is accounting for absorbed solar + // radiation originating from beam on exterior side. Third item (SurfWinACFOverlap(SurfNum,Lay)) is + // accounting for absorptances from beam hitting back of the window which passes through rest of exterior + // windows + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = + state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.State(CurrentState).WinSkyFtAbs(Lay) * SkySolarInc + + state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.State(CurrentState).WinSkyGndAbs(Lay) * GndSolarInc + + state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar + + state.dataSurface->SurfWinACFOverlap(SurfNum, Lay) * BeamSolar; + } + // Total solar absorbed in solid layer (W), for reporting + state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) = + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area; - // Total solar absorbed in all glass layers (W), for reporting - state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay); - } - state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) = - state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec; - // Need to do it this way for now beaucse of scheduled surface gains. They do work only with - // BSDF windows and overwriting absorbtances will work only for ordinary windows - // } else if ( SurfaceWindow( SurfNum ).WindowModelType != WindowModel:: BSDF && - // SurfaceWindow( SurfNum ).WindowModelType != WindowModel:: EQL && - // inExtWindowModel->isExternalLibraryModel() ) { - // TotSolidLay = Construct( ConstrNum ).TotSolidLayers; - // for ( Lay = 1; Lay <= TotSolidLay; ++Lay ) { - // SurfWinQRadSWwinAbs( Lay, SurfNum ) = SurfWinA( Lay, SurfNum ) * - // ( SurfQRadSWOutIncident( SurfNum ) + QS( Surface( SurfNum ).Zone ) ); - // } - } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) { - int TotSolidLay = state.dataConstruction->Construct(ConstrNum).TotSolidLayers; - // Number of solid layers in fenestration system (glass + shading) - int CurrentState = state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.CurrentState; - // Current state for Complex Fenestration - // Examine for schedule surface gain - Real64 SurfSolAbs = WindowScheduledSolarAbs(state, - SurfNum, - ConstrNum); // Pointer to scheduled surface gains object for fenestration systems - - for (int Lay = 1; Lay <= TotSolidLay; ++Lay) { - if (SurfSolAbs != 0) { - state.dataSurface->SurfWinA(SurfNum, Lay) = - GetCurrentScheduleValue(state, state.dataSurface->FenLayAbsSSG(SurfSolAbs).SchedPtrs(Lay)); - // ABWin(Lay) = SurfWinA(SurfNum,Lay) - state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = state.dataSurface->SurfWinA(SurfNum, Lay); - } else { - // Several notes about this equation. First part is accounting for duffuse solar radiation for the ground - // and from the sky. Second item (SurfWinA(SurfNum,Lay) * BeamSolar) is accounting for absorbed solar - // radiation originating from beam on exterior side. Third item (SurfWinACFOverlap(SurfNum,Lay)) is - // accounting for absorptances from beam hitting back of the window which passes through rest of exterior - // windows - state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = - state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.State(CurrentState).WinSkyFtAbs(Lay) * SkySolarInc + - state.dataSurface->SurfaceWindow(SurfNum).ComplexFen.State(CurrentState).WinSkyGndAbs(Lay) * GndSolarInc + - state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar + - state.dataSurface->SurfWinACFOverlap(SurfNum, Lay) * BeamSolar; + // Total solar absorbed in all glass layers (W), for reporting + state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay); } - // Total solar absorbed in solid layer (W), for reporting - state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) = - state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area; + state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) = + state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec; + + } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::EQL) { + state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0; + // EQLNum = Construct(Surface(SurfNum)%Construction)%EQLConsPtr + int TotSolidLay = + state.dataWindowEquivLayer->CFS(state.dataConstruction->Construct(Surface(SurfNum).Construction).EQLConsPtr).NL; + for (int Lay = 1; Lay <= TotSolidLay; ++Lay) { + // Absorbed window components include: + // (1) beam solar radiation absorbed by all layers in the fenestration + // (2) sky and ground reflected duffuse solar radiation absorbed by all layers + // (3) diffuse short wave incident on the inside face of the fenestration. The short wave internal sources + // include light, ... + AbsDiffWin(Lay) = state.dataConstruction->Construct(ConstrNum).AbsDiffFrontEQL(Lay); + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = + state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar + AbsDiffWin(Lay) * (SkySolarInc + GndSolarInc); - // Total solar absorbed in all glass layers (W), for reporting - state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay); - } - state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) = - state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec; - - } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::EQL) { - state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0; - // EQLNum = Construct(Surface(SurfNum)%Construction)%EQLConsPtr - int TotSolidLay = - state.dataWindowEquivLayer->CFS(state.dataConstruction->Construct(Surface(SurfNum).Construction).EQLConsPtr).NL; - for (int Lay = 1; Lay <= TotSolidLay; ++Lay) { - // Absorbed window components include: - // (1) beam solar radiation absorbed by all layers in the fenestration - // (2) sky and ground reflected duffuse solar radiation absorbed by all layers - // (3) diffuse short wave incident on the inside face of the fenestration. The short wave internal sources - // include light, ... - AbsDiffWin(Lay) = state.dataConstruction->Construct(ConstrNum).AbsDiffFrontEQL(Lay); - state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = - state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar + AbsDiffWin(Lay) * (SkySolarInc + GndSolarInc); - - // Total solar absorbed in solid layer (W), for reporting - state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) = - state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area; - - // Total solar absorbed in all glass layers (W), for reporting - state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay); - } + // Total solar absorbed in solid layer (W), for reporting + state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) = + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area; - state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) = - state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec; - } else if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) { - int SurfNum2 = SurfNum; - if (state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::TDD_Diffuser) { - SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(SurfNum)).Dome; - } + // Total solar absorbed in all glass layers (W), for reporting + state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay); + } - std::pair incomingAngle = getSunWCEAngles(state, SurfNum2, BSDFDirection::Incoming); - Real64 Theta = incomingAngle.first; - Real64 Phi = incomingAngle.second; + state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) = + state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) * state.dataGlobal->TimeStepZoneSec; + } else if (state.dataWindowManager->inExtWindowModel->isExternalLibraryModel()) { + int SurfNum2 = SurfNum; + if (state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::TDD_Diffuser) { + SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(SurfNum)).Dome; + } - std::shared_ptr aLayer = - CWindowConstructionsSimplified::instance().getEquivalentLayer(state, WavelengthRange::Solar, ConstrNum); + std::pair incomingAngle = getSunWCEAngles(state, SurfNum2, BSDFDirection::Incoming); + Real64 Theta = incomingAngle.first; + Real64 Phi = incomingAngle.second; - size_t totLayers = aLayer->getNumOfLayers(); - for (size_t Lay = 1; Lay <= totLayers; ++Lay) { - Real64 AbWinDiff = aLayer->getAbsorptanceLayer(Lay, Side::Front, ScatteringSimple::Diffuse, Theta, Phi); + std::shared_ptr aLayer = + CWindowConstructionsSimplified::instance().getEquivalentLayer(state, WavelengthRange::Solar, ConstrNum); - state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = - AbWinDiff * (SkySolarInc + GndSolarInc) + state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar; + size_t totLayers = aLayer->getNumOfLayers(); + for (size_t Lay = 1; Lay <= totLayers; ++Lay) { + Real64 AbWinDiff = aLayer->getAbsorptanceLayer(Lay, Side::Front, ScatteringSimple::Diffuse, Theta, Phi); - // Total solar absorbed in solid layer (W), for reporting - state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) = - state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area; + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) = + AbWinDiff * (SkySolarInc + GndSolarInc) + state.dataSurface->SurfWinA(SurfNum, Lay) * BeamSolar; - // Total solar absorbed in all glass layers (W), for reporting - state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay); - } - } + // Total solar absorbed in solid layer (W), for reporting + state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay) = + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) * Surface(SurfNum).Area; - // Solar absorbed by window frame and dividers - int FrDivNum = Surface(SurfNum).FrameDivider; // Frame/divider number - if (FrDivNum > 0) { - Real64 FrArea = state.dataSurface->SurfWinFrameArea(SurfNum); // Frame, divider area (m2) - Real64 FrProjOut = state.dataSurface->FrameDivider(FrDivNum).FrameProjectionOut; // Frame, divider outside projection (m) - Real64 FrProjIn = state.dataSurface->FrameDivider(FrDivNum).FrameProjectionIn; - Real64 DivArea = state.dataSurface->SurfWinDividerArea(SurfNum); - Real64 DivWidth = state.dataSurface->FrameDivider(FrDivNum).DividerWidth; - Real64 DivProjOut = state.dataSurface->FrameDivider(FrDivNum).DividerProjectionOut; - Real64 DivProjIn = state.dataSurface->FrameDivider(FrDivNum).DividerProjectionIn; - Real64 CosIncAngHorProj = 0.0; // Cosine of incidence angle of sun on horizontal faces of a frame or divider projection - Real64 CosIncAngVertProj = 0.0; // Cosine of incidence angle of sun on vertical faces of a frame or divider projection - Real64 FracSunLit = 0.0; // Fraction of window sunlit this time step - Real64 BeamFaceInc; // Beam solar incident window plane this time step (W/m2) - Real64 DifSolarFaceInc; // Diffuse solar incident on window plane this time step (W/m2) - Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier; - Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier; - if (FrArea > 0.0 || DivArea > 0.0) { - FracSunLit = state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum); - BeamFaceInc = currBeamSolarRad * - state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) * - CosInc; - DifSolarFaceInc = SkySolarInc + GndSolarInc; - } - if (FracSunLit > 0.0) { - if ((FrArea > 0.0 && (FrProjOut > 0.0 || FrProjIn > 0.0)) || (DivArea > 0.0 && (DivProjOut > 0.0 || DivProjIn > 0.0))) { - // Dot products used to calculate beam solar incident on faces of - // frame and divider perpendicular to the glass surface. - // Note that SOLCOS is the current timestep's solar direction cosines. - // PhiWin = ASIN(WALCOS(3,SurfNum)) - Real64 PhiWin = - std::asin(Surface(SurfNum).OutNormVec(3)); // Altitude and azimuth angle of outward window normal (radians) - Real64 ThWin = std::atan2(Surface(SurfNum).OutNormVec(2), Surface(SurfNum).OutNormVec(1)); - Real64 PhiSun = std::asin(state.dataEnvrn->SOLCOS(3)); // Altitude and azimuth angle of sun (radians) - Real64 ThSun = std::atan2(state.dataEnvrn->SOLCOS(2), state.dataEnvrn->SOLCOS(1)); - Real64 const cos_PhiWin(std::cos(PhiWin)); - Real64 const cos_PhiSun(std::cos(PhiSun)); - CosIncAngHorProj = std::abs(std::sin(PhiWin) * cos_PhiSun * std::cos(ThWin - ThSun) - cos_PhiWin * std::sin(PhiSun)); - CosIncAngVertProj = std::abs(cos_PhiWin * cos_PhiSun * std::sin(ThWin - ThSun)); + // Total solar absorbed in all glass layers (W), for reporting + state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) += state.dataHeatBal->SurfWinQRadSWwinAbsLayer(SurfNum, Lay); } } - // Frame solar - // (A window shade or blind, if present, is assumed to not shade the frame, so no special - // treatment of frame solar needed if window has an exterior shade or blind.) - if (FrArea > 0.0) { - Real64 FrIncSolarOut = BeamFaceInc; // Total solar incident on outside offrame including solar - Real64 FrIncSolarIn = 0.0; // Total solar incident on inside offrame including solar on frame projection (W/m2) - Real64 TransDiffGl = 0.0; // Diffuse solar transmittance - if (FrProjOut > 0.0 || FrProjIn > 0.0) { - Real64 BeamFrHorFaceInc = - currBeamSolarRad * CosIncAngHorProj * - (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) * FracSunLit / - FrArea; - Real64 BeamFrVertFaceInc = - currBeamSolarRad * CosIncAngVertProj * - (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) * FracSunLit / - FrArea; - // Beam solar on outside of frame - FrIncSolarOut += (BeamFrHorFaceInc + BeamFrVertFaceInc) * FrProjOut; - if (FrProjIn > 0.0) { - Real64 TransGl = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).TransSolBeamCoef); - TransDiffGl = state.dataConstruction->Construct(ConstrNum).TransDiff; - if (ShadeFlag == WinShadingType::SwitchableGlazing) { // Switchable glazing - Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum); - int ConstrNumSh = Surface(SurfNum).activeShadedConstruction; - Real64 TransGlSh = POLYF(CosInc, state.dataConstruction->Construct(ConstrNumSh).TransSolBeamCoef); - TransGl = InterpSw(SwitchFac, TransGl, TransGlSh); - Real64 TransDiffGlSh = state.dataConstruction->Construct(ConstrNumSh).TransDiff; - TransDiffGl = InterpSw(SwitchFac, TransDiffGl, TransDiffGlSh); - } - // Beam solar on inside of frame - FrIncSolarIn = (BeamFrHorFaceInc + BeamFrVertFaceInc) * FrProjIn * TransGl; + + // Solar absorbed by window frame and dividers + int FrDivNum = Surface(SurfNum).FrameDivider; // Frame/divider number + if (FrDivNum > 0) { + Real64 FrArea = state.dataSurface->SurfWinFrameArea(SurfNum); // Frame, divider area (m2) + Real64 FrProjOut = state.dataSurface->FrameDivider(FrDivNum).FrameProjectionOut; // Frame, divider outside projection (m) + Real64 FrProjIn = state.dataSurface->FrameDivider(FrDivNum).FrameProjectionIn; + Real64 DivArea = state.dataSurface->SurfWinDividerArea(SurfNum); + Real64 DivWidth = state.dataSurface->FrameDivider(FrDivNum).DividerWidth; + Real64 DivProjOut = state.dataSurface->FrameDivider(FrDivNum).DividerProjectionOut; + Real64 DivProjIn = state.dataSurface->FrameDivider(FrDivNum).DividerProjectionIn; + Real64 CosIncAngHorProj = 0.0; // Cosine of incidence angle of sun on horizontal faces of a frame or divider projection + Real64 CosIncAngVertProj = 0.0; // Cosine of incidence angle of sun on vertical faces of a frame or divider projection + Real64 FracSunLit = 0.0; // Fraction of window sunlit this time step + Real64 BeamFaceInc; // Beam solar incident window plane this time step (W/m2) + Real64 DifSolarFaceInc; // Diffuse solar incident on window plane this time step (W/m2) + Real64 SurfIncSolarMultiplier = state.dataSurface->Surface(SurfNum).IncSolMultiplier; + Real64 currBeamSolarRad = state.dataEnvrn->BeamSolarRad * SurfIncSolarMultiplier; + if (FrArea > 0.0 || DivArea > 0.0) { + FracSunLit = state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum); + BeamFaceInc = currBeamSolarRad * + state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) * + CosInc; + DifSolarFaceInc = SkySolarInc + GndSolarInc; + } + if (FracSunLit > 0.0) { + if ((FrArea > 0.0 && (FrProjOut > 0.0 || FrProjIn > 0.0)) || + (DivArea > 0.0 && (DivProjOut > 0.0 || DivProjIn > 0.0))) { + // Dot products used to calculate beam solar incident on faces of + // frame and divider perpendicular to the glass surface. + // Note that SOLCOS is the current timestep's solar direction cosines. + // PhiWin = ASIN(WALCOS(3,SurfNum)) + Real64 PhiWin = + std::asin(Surface(SurfNum).OutNormVec(3)); // Altitude and azimuth angle of outward window normal (radians) + Real64 ThWin = std::atan2(Surface(SurfNum).OutNormVec(2), Surface(SurfNum).OutNormVec(1)); + Real64 PhiSun = std::asin(state.dataEnvrn->SOLCOS(3)); // Altitude and azimuth angle of sun (radians) + Real64 ThSun = std::atan2(state.dataEnvrn->SOLCOS(2), state.dataEnvrn->SOLCOS(1)); + Real64 const cos_PhiWin(std::cos(PhiWin)); + Real64 const cos_PhiSun(std::cos(PhiSun)); + CosIncAngHorProj = + std::abs(std::sin(PhiWin) * cos_PhiSun * std::cos(ThWin - ThSun) - cos_PhiWin * std::sin(PhiSun)); + CosIncAngVertProj = std::abs(cos_PhiWin * cos_PhiSun * std::sin(ThWin - ThSun)); } } - // Beam plus diffuse solar on outside of frame - FrIncSolarOut += DifSolarFaceInc * (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrOut(SurfNum)); - state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) = FrIncSolarOut * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum); - // Add diffuse from beam reflected from window outside reveal surfaces - state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) += currBeamSolarRad * - state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) * - state.dataSurface->SurfWinFrameSolAbsorp(SurfNum); - - // Beam plus diffuse solar on inside of frame - FrIncSolarIn += DifSolarFaceInc * TransDiffGl * 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum); - state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) = FrIncSolarIn * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum); - // Add diffuse from beam reflected from window inside reveal surfaces - state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) += currBeamSolarRad * - state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) * - state.dataSurface->SurfWinFrameSolAbsorp(SurfNum); - } - - // Divider solar - // (An exterior shade or blind, when in place, is assumed to completely cover the divider. - // Dividers are not allowed on windows with between-glass shade/blind so DivProjOut and - // DivProjIn will be zero in this case.) - if (DivArea > 0.0) { // Solar absorbed by window divider - Real64 DividerAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance - if (state.dataSurface->SurfWinDividerType(SurfNum) == DataSurfaces::FrameDividerType::Suspended) { - // Suspended (between-glass) divider; account for effect glass on outside of divider - // (note that outside and inside projection for this type of divider are both zero) - int MatNumGl = state.dataConstruction->Construct(ConstrNum).LayerPoint(1); // Outer glass layer material number - Real64 TransGl = - state.dataMaterial->Material(MatNumGl).Trans; // Outer glass layer material number, switched construction - Real64 ReflGl = state.dataMaterial->Material(MatNumGl).ReflectSolBeamFront; - Real64 AbsGl = 1.0 - TransGl - ReflGl; - Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum); - int ConstrNumSh = Surface(SurfNum).activeShadedConstruction; - if (ShadeFlag == WinShadingType::SwitchableGlazing) { // Switchable glazing - Real64 MatNumGlSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(1); - Real64 TransGlSh = state.dataMaterial->Material(MatNumGlSh).Trans; - Real64 ReflGlSh = state.dataMaterial->Material(MatNumGlSh).ReflectSolBeamFront; - Real64 AbsGlSh = 1.0 - TransGlSh - ReflGlSh; - TransGl = InterpSw(SwitchFac, TransGl, TransGlSh); - ReflGl = InterpSw(SwitchFac, ReflGl, ReflGlSh); - AbsGl = InterpSw(SwitchFac, AbsGl, AbsGlSh); + // Frame solar + // (A window shade or blind, if present, is assumed to not shade the frame, so no special + // treatment of frame solar needed if window has an exterior shade or blind.) + if (FrArea > 0.0) { + Real64 FrIncSolarOut = BeamFaceInc; // Total solar incident on outside offrame including solar + Real64 FrIncSolarIn = 0.0; // Total solar incident on inside offrame including solar on frame projection (W/m2) + Real64 TransDiffGl = 0.0; // Diffuse solar transmittance + if (FrProjOut > 0.0 || FrProjIn > 0.0) { + Real64 BeamFrHorFaceInc = + currBeamSolarRad * CosIncAngHorProj * + (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) * FracSunLit / + FrArea; + Real64 BeamFrVertFaceInc = + currBeamSolarRad * CosIncAngVertProj * + (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) * FracSunLit / + FrArea; + // Beam solar on outside of frame + FrIncSolarOut += (BeamFrHorFaceInc + BeamFrVertFaceInc) * FrProjOut; + if (FrProjIn > 0.0) { + Real64 TransGl = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).TransSolBeamCoef); + TransDiffGl = state.dataConstruction->Construct(ConstrNum).TransDiff; + if (ShadeFlag == WinShadingType::SwitchableGlazing) { // Switchable glazing + Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum); + int ConstrNumSh = Surface(SurfNum).activeShadedConstruction; + Real64 TransGlSh = POLYF(CosInc, state.dataConstruction->Construct(ConstrNumSh).TransSolBeamCoef); + TransGl = InterpSw(SwitchFac, TransGl, TransGlSh); + Real64 TransDiffGlSh = state.dataConstruction->Construct(ConstrNumSh).TransDiff; + TransDiffGl = InterpSw(SwitchFac, TransDiffGl, TransDiffGlSh); + } + // Beam solar on inside of frame + FrIncSolarIn = (BeamFrHorFaceInc + BeamFrVertFaceInc) * FrProjIn * TransGl; + } } - Real64 DividerRefl = 1.0 - DividerAbs; // Window divider solar reflectance - DividerAbs = AbsGl + TransGl * (DividerAbs + DividerRefl * AbsGl) / (1.0 - DividerRefl * ReflGl); + // Beam plus diffuse solar on outside of frame + FrIncSolarOut += DifSolarFaceInc * (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrOut(SurfNum)); + state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) = + FrIncSolarOut * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum); + // Add diffuse from beam reflected from window outside reveal surfaces + state.dataSurface->SurfWinFrameQRadOutAbs(SurfNum) += currBeamSolarRad * + state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) * + state.dataSurface->SurfWinFrameSolAbsorp(SurfNum); + + // Beam plus diffuse solar on inside of frame + FrIncSolarIn += DifSolarFaceInc * TransDiffGl * 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum); + state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) = FrIncSolarIn * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum); + // Add diffuse from beam reflected from window inside reveal surfaces + state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) += currBeamSolarRad * + state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) * + state.dataSurface->SurfWinFrameSolAbsorp(SurfNum); } - Real64 BeamDivHorFaceInc = 0.0; // Beam solar on divider's horizontal outside projection faces (W/m2) - Real64 BeamDivVertFaceInc = 0.0; // Beam solar on divider's vertical outside projection faces (W/m2) - // Beam incident on horizontal and vertical projection faces of divider if no exterior shading - if (DivProjOut > 0.0 && !ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) { - BeamDivHorFaceInc = currBeamSolarRad * CosIncAngHorProj * state.dataSurface->FrameDivider(FrDivNum).HorDividers * - DivProjOut * - (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) * - FracSunLit / DivArea; - BeamDivVertFaceInc = currBeamSolarRad * CosIncAngVertProj * state.dataSurface->FrameDivider(FrDivNum).VertDividers * - DivProjOut * - (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) * - FracSunLit / DivArea; - } - Real64 DivIncSolarOutBm = 0.0; // Diffuse solar incident on outside of divider including beam on divider projection (W/m2) - Real64 DivIncSolarOutDif = - 0.0; // Diffuse solar incident on outside of divider including diffuse on divider projection (W/m2) - Real64 DivIncSolarInBm = 0.0; // Diffuse solar incident on inside of divider including beam on divider projection (W/m2) - Real64 DivIncSolarInDif = - 0.0; // Diffuse solar incident on inside of divider including diffuse on divider projection (W/m2) - if (!ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag) && - !ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) { // No exterior or between-glass shading - DivIncSolarOutBm = BeamFaceInc + BeamDivHorFaceInc + BeamDivVertFaceInc; - DivIncSolarOutDif = DifSolarFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum)); - if (DivProjIn > 0.0) { - Real64 TransGl = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).TransSolBeamCoef); - Real64 TransDiffGl = state.dataConstruction->Construct(ConstrNum).TransDiff; // Diffuse solar transmittance - if (ShadeFlag == WinShadingType::SwitchableGlazing) { // Switchable glazing - Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum); - int ConstrNumSh = Surface(SurfNum).activeShadedConstruction; - Real64 TransGlSh = POLYF(CosInc, state.dataConstruction->Construct(ConstrNumSh).TransSolBeamCoef); - // Outer glass solar trans, refl, absorptance if switched + // Divider solar + // (An exterior shade or blind, when in place, is assumed to completely cover the divider. + // Dividers are not allowed on windows with between-glass shade/blind so DivProjOut and + // DivProjIn will be zero in this case.) + if (DivArea > 0.0) { // Solar absorbed by window divider + Real64 DividerAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance + if (state.dataSurface->SurfWinDividerType(SurfNum) == DataSurfaces::FrameDividerType::Suspended) { + // Suspended (between-glass) divider; account for effect glass on outside of divider + // (note that outside and inside projection for this type of divider are both zero) + int MatNumGl = state.dataConstruction->Construct(ConstrNum).LayerPoint(1); // Outer glass layer material number + Real64 TransGl = + state.dataMaterial->Material(MatNumGl).Trans; // Outer glass layer material number, switched construction + Real64 ReflGl = state.dataMaterial->Material(MatNumGl).ReflectSolBeamFront; + Real64 AbsGl = 1.0 - TransGl - ReflGl; + Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum); + int ConstrNumSh = Surface(SurfNum).activeShadedConstruction; + if (ShadeFlag == WinShadingType::SwitchableGlazing) { // Switchable glazing + Real64 MatNumGlSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(1); + Real64 TransGlSh = state.dataMaterial->Material(MatNumGlSh).Trans; + Real64 ReflGlSh = state.dataMaterial->Material(MatNumGlSh).ReflectSolBeamFront; + Real64 AbsGlSh = 1.0 - TransGlSh - ReflGlSh; TransGl = InterpSw(SwitchFac, TransGl, TransGlSh); - Real64 TransDiffGlSh = state.dataConstruction->Construct(ConstrNumSh).TransDiff; - // Diffuse solar transmittance, switched construction - TransDiffGl = InterpSw(SwitchFac, TransDiffGl, TransDiffGlSh); + ReflGl = InterpSw(SwitchFac, ReflGl, ReflGlSh); + AbsGl = InterpSw(SwitchFac, AbsGl, AbsGlSh); } - // Beam plus diffuse solar on inside of divider - // BeamDivHorFaceIncIn - Beam solar on divider's horizontal inside projection faces (W/m2) - // BeamDivVertFaceIncIn - Beam solar on divider's vertical inside projection faces (W/m2) - Real64 BeamDivHorFaceIncIn = - currBeamSolarRad * CosIncAngHorProj * state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivProjIn * - (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) * FracSunLit / - DivArea; - Real64 BeamDivVertFaceIncIn = - currBeamSolarRad * CosIncAngVertProj * state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivProjIn * + Real64 DividerRefl = 1.0 - DividerAbs; // Window divider solar reflectance + DividerAbs = AbsGl + TransGl * (DividerAbs + DividerRefl * AbsGl) / (1.0 - DividerRefl * ReflGl); + } + + Real64 BeamDivHorFaceInc = 0.0; // Beam solar on divider's horizontal outside projection faces (W/m2) + Real64 BeamDivVertFaceInc = 0.0; // Beam solar on divider's vertical outside projection faces (W/m2) + // Beam incident on horizontal and vertical projection faces of divider if no exterior shading + if (DivProjOut > 0.0 && !ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) { + BeamDivHorFaceInc = currBeamSolarRad * CosIncAngHorProj * state.dataSurface->FrameDivider(FrDivNum).HorDividers * + DivProjOut * + (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) * + FracSunLit / DivArea; + BeamDivVertFaceInc = + currBeamSolarRad * CosIncAngVertProj * state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivProjOut * (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) * FracSunLit / DivArea; - DivIncSolarInBm = TransGl * (BeamDivHorFaceIncIn + BeamDivVertFaceIncIn); - DivIncSolarInDif = TransDiffGl * DifSolarFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum); } - } else { // Exterior shade, screen or blind present - - DivIncSolarOutBm = BeamFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum)); - DivIncSolarOutDif = DifSolarFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum)); - DivIncSolarInBm = BeamFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum) * - state.dataConstruction->Construct(ConstrNum).TransDiff; - DivIncSolarInDif = DifSolarFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum) * - state.dataConstruction->Construct(ConstrNum).TransDiff; - } - if (!ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag) && !ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) { - // No exterior or between-glass shade, screen or blind - state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) = DividerAbs * (DivIncSolarOutBm + DivIncSolarOutDif); - state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) = DividerAbs * (DivIncSolarInBm + DivIncSolarInDif); - // Exterior shade, screen or blind - } else if (ShadeFlag == WinShadingType::ExtBlind) { // Exterior blind - int BlNum = state.dataSurface->SurfWinBlindNumber(SurfNum); - int SlatsAngIndexLower = state.dataSurface->SurfWinSlatsAngIndex(SurfNum); - int SlatsAngIndexUpper = std::min(MaxProfAngs, SlatsAngIndexLower + 1); - Real64 SlatsAngInterpFac = state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum); - - Real64 FrontDiffTrans; - Real64 TBlBmDif; // Blind diffuse-diffuse solar transmittance - if (state.dataSurface->SurfWinMovableSlats(SurfNum)) { - FrontDiffTrans = General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffTrans(SlatsAngIndexLower), - state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffTrans(SlatsAngIndexUpper), - SlatsAngInterpFac); - TBlBmDif = General::InterpProfSlat( - state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(SlatsAngIndexLower, - state.dataSurface->SurfWinProfAngIndex(SurfNum)), - state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(SlatsAngIndexUpper, - state.dataSurface->SurfWinProfAngIndex(SurfNum)), - state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans( - SlatsAngIndexLower, std::min(MaxProfAngs, state.dataSurface->SurfWinProfAngIndex(SurfNum) + 1)), - state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans( - SlatsAngIndexUpper, std::min(MaxProfAngs, state.dataSurface->SurfWinProfAngIndex(SurfNum) + 1)), - SlatsAngInterpFac, - state.dataSurface->SurfWinProfAngInterpFac(SurfNum)); - } else { - FrontDiffTrans = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffTrans(1); - TBlBmDif = General::InterpGeneral( - state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(1, state.dataSurface->SurfWinProfAngIndex(SurfNum)), - state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans( - 1, std::min(MaxProfAngs, state.dataSurface->SurfWinProfAngIndex(SurfNum) + 1)), - SlatsAngInterpFac); + Real64 DivIncSolarOutBm = + 0.0; // Diffuse solar incident on outside of divider including beam on divider projection (W/m2) + Real64 DivIncSolarOutDif = + 0.0; // Diffuse solar incident on outside of divider including diffuse on divider projection (W/m2) + Real64 DivIncSolarInBm = + 0.0; // Diffuse solar incident on inside of divider including beam on divider projection (W/m2) + Real64 DivIncSolarInDif = + 0.0; // Diffuse solar incident on inside of divider including diffuse on divider projection (W/m2) + if (!ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag) && + !ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) { // No exterior or between-glass shading + DivIncSolarOutBm = BeamFaceInc + BeamDivHorFaceInc + BeamDivVertFaceInc; + DivIncSolarOutDif = DifSolarFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum)); + if (DivProjIn > 0.0) { + Real64 TransGl = POLYF(CosInc, state.dataConstruction->Construct(ConstrNum).TransSolBeamCoef); + Real64 TransDiffGl = state.dataConstruction->Construct(ConstrNum).TransDiff; // Diffuse solar transmittance + if (ShadeFlag == WinShadingType::SwitchableGlazing) { // Switchable glazing + Real64 SwitchFac = state.dataSurface->SurfWinSwitchingFactor(SurfNum); + int ConstrNumSh = Surface(SurfNum).activeShadedConstruction; + Real64 TransGlSh = POLYF(CosInc, state.dataConstruction->Construct(ConstrNumSh).TransSolBeamCoef); + // Outer glass solar trans, refl, absorptance if switched + TransGl = InterpSw(SwitchFac, TransGl, TransGlSh); + Real64 TransDiffGlSh = state.dataConstruction->Construct(ConstrNumSh).TransDiff; + // Diffuse solar transmittance, switched construction + TransDiffGl = InterpSw(SwitchFac, TransDiffGl, TransDiffGlSh); + } + // Beam plus diffuse solar on inside of divider + // BeamDivHorFaceIncIn - Beam solar on divider's horizontal inside projection faces (W/m2) + // BeamDivVertFaceIncIn - Beam solar on divider's vertical inside projection faces (W/m2) + Real64 BeamDivHorFaceIncIn = + currBeamSolarRad * CosIncAngHorProj * state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivProjIn * + (Surface(SurfNum).Width - state.dataSurface->FrameDivider(FrDivNum).VertDividers * DivWidth) * + FracSunLit / DivArea; + Real64 BeamDivVertFaceIncIn = + currBeamSolarRad * CosIncAngVertProj * state.dataSurface->FrameDivider(FrDivNum).VertDividers * + DivProjIn * (Surface(SurfNum).Height - state.dataSurface->FrameDivider(FrDivNum).HorDividers * DivWidth) * + FracSunLit / DivArea; + DivIncSolarInBm = TransGl * (BeamDivHorFaceIncIn + BeamDivVertFaceIncIn); + DivIncSolarInDif = TransDiffGl * DifSolarFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum); + } + } else { // Exterior shade, screen or blind present + + DivIncSolarOutBm = BeamFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum)); + DivIncSolarOutDif = DifSolarFaceInc * (1.0 + state.dataSurface->SurfWinProjCorrDivOut(SurfNum)); + DivIncSolarInBm = BeamFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum) * + state.dataConstruction->Construct(ConstrNum).TransDiff; + DivIncSolarInDif = DifSolarFaceInc * state.dataSurface->SurfWinProjCorrDivIn(SurfNum) * + state.dataConstruction->Construct(ConstrNum).TransDiff; } + if (!ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag) && !ANY_BETWEENGLASS_SHADE_BLIND(ShadeFlag)) { + // No exterior or between-glass shade, screen or blind + state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) = DividerAbs * (DivIncSolarOutBm + DivIncSolarOutDif); + state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) = DividerAbs * (DivIncSolarInBm + DivIncSolarInDif); + // Exterior shade, screen or blind + } else if (ShadeFlag == WinShadingType::ExtBlind) { // Exterior blind + int BlNum = state.dataSurface->SurfWinBlindNumber(SurfNum); + int SlatsAngIndexLower = state.dataSurface->SurfWinSlatsAngIndex(SurfNum); + int SlatsAngIndexUpper = std::min(MaxProfAngs, SlatsAngIndexLower + 1); + Real64 SlatsAngInterpFac = state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum); + + Real64 FrontDiffTrans; + Real64 TBlBmDif; // Blind diffuse-diffuse solar transmittance + if (state.dataSurface->SurfWinMovableSlats(SurfNum)) { + FrontDiffTrans = + General::InterpGeneral(state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffTrans(SlatsAngIndexLower), + state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffTrans(SlatsAngIndexUpper), + SlatsAngInterpFac); + TBlBmDif = General::InterpProfSlat( + state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(SlatsAngIndexLower, + state.dataSurface->SurfWinProfAngIndex(SurfNum)), + state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(SlatsAngIndexUpper, + state.dataSurface->SurfWinProfAngIndex(SurfNum)), + state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans( + SlatsAngIndexLower, std::min(MaxProfAngs, state.dataSurface->SurfWinProfAngIndex(SurfNum) + 1)), + state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans( + SlatsAngIndexUpper, std::min(MaxProfAngs, state.dataSurface->SurfWinProfAngIndex(SurfNum) + 1)), + SlatsAngInterpFac, + state.dataSurface->SurfWinProfAngInterpFac(SurfNum)); + } else { + FrontDiffTrans = state.dataHeatBal->Blind(BlNum).SolFrontDiffDiffTrans(1); + TBlBmDif = General::InterpGeneral( + state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans(1, state.dataSurface->SurfWinProfAngIndex(SurfNum)), + state.dataHeatBal->Blind(BlNum).SolFrontBeamDiffTrans( + 1, std::min(MaxProfAngs, state.dataSurface->SurfWinProfAngIndex(SurfNum) + 1)), + SlatsAngInterpFac); + } - // TBlBmBm - Blind beam-beam solar transmittance - Real64 TBlBmBm = state.dataSurface->SurfWinBlindBmBmTrans(SurfNum); - state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) = - DividerAbs * (DivIncSolarOutBm * (TBlBmBm + TBlBmDif) + DivIncSolarOutDif * FrontDiffTrans); - state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) = - DividerAbs * (DivIncSolarInBm * (TBlBmBm + TBlBmDif) + DivIncSolarInDif * FrontDiffTrans); - - } else if (ShadeFlag == WinShadingType::ExtShade) { // Exterior shade - int ConstrNumSh = Surface(SurfNum).activeShadedConstruction; - state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) = - DividerAbs * state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumSh).LayerPoint(1)).Trans * - (DivIncSolarOutBm + DivIncSolarOutDif); - state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) = - DividerAbs * state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumSh).LayerPoint(1)).Trans * - (DivIncSolarInBm + DivIncSolarInDif); - - } else if (ShadeFlag == WinShadingType::ExtScreen) { // Exterior screen - state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) = - DividerAbs * - (state.dataHeatBal->SurfaceScreens(state.dataSurface->SurfWinScreenNumber(SurfNum)).BmBmTrans + - state.dataHeatBal->SurfaceScreens(state.dataSurface->SurfWinScreenNumber(SurfNum)).BmDifTrans) * - (DivIncSolarOutBm + DivIncSolarOutDif); - state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) = - DividerAbs * - (state.dataHeatBal->SurfaceScreens(state.dataSurface->SurfWinScreenNumber(SurfNum)).BmBmTrans + - state.dataHeatBal->SurfaceScreens(state.dataSurface->SurfWinScreenNumber(SurfNum)).BmDifTrans) * - (DivIncSolarInBm + DivIncSolarInDif); + // TBlBmBm - Blind beam-beam solar transmittance + Real64 TBlBmBm = state.dataSurface->SurfWinBlindBmBmTrans(SurfNum); + state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) = + DividerAbs * (DivIncSolarOutBm * (TBlBmBm + TBlBmDif) + DivIncSolarOutDif * FrontDiffTrans); + state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) = + DividerAbs * (DivIncSolarInBm * (TBlBmBm + TBlBmDif) + DivIncSolarInDif * FrontDiffTrans); + + } else if (ShadeFlag == WinShadingType::ExtShade) { // Exterior shade + int ConstrNumSh = Surface(SurfNum).activeShadedConstruction; + state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) = + DividerAbs * + state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumSh).LayerPoint(1)).Trans * + (DivIncSolarOutBm + DivIncSolarOutDif); + state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) = + DividerAbs * + state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumSh).LayerPoint(1)).Trans * + (DivIncSolarInBm + DivIncSolarInDif); + + } else if (ShadeFlag == WinShadingType::ExtScreen) { // Exterior screen + state.dataSurface->SurfWinDividerQRadOutAbs(SurfNum) = + DividerAbs * + (state.dataHeatBal->SurfaceScreens(state.dataSurface->SurfWinScreenNumber(SurfNum)).BmBmTrans + + state.dataHeatBal->SurfaceScreens(state.dataSurface->SurfWinScreenNumber(SurfNum)).BmDifTrans) * + (DivIncSolarOutBm + DivIncSolarOutDif); + state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) = + DividerAbs * + (state.dataHeatBal->SurfaceScreens(state.dataSurface->SurfWinScreenNumber(SurfNum)).BmBmTrans + + state.dataHeatBal->SurfaceScreens(state.dataSurface->SurfWinScreenNumber(SurfNum)).BmDifTrans) * + (DivIncSolarInBm + DivIncSolarInDif); + } } } - } - } // Surface(SurfNum)%ExtSolar - } // end of surface window loop - } // end of zone loop + } // Surface(SurfNum)%ExtSolar + } // end of surface window loop + } // end of space loop + } // end of zone loop for (int PipeNum = 1; PipeNum <= (int)state.dataDaylightingDevicesData->TDDPipe.size(); ++PipeNum) { int const SurfNum = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome; // TDD: DOME object number int const ConstrNum = Surface(SurfNum).Construction; @@ -3548,75 +3570,80 @@ void InitSolarHeatGains(EnergyPlusData &state) // Average absorbed solar for representative surfaces if (state.dataSurface->UseRepresentativeSurfaceCalculations) { for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int firstSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceFirst; - int lastSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceLast; - for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - auto &surface(state.dataSurface->Surface(surfNum)); - if (surface.ConstituentSurfaceNums.size() > 1) { - Real64 QoutAtot = 0.0; - Real64 QinAtot = 0.0; - Real64 Atot = 0.0; - for (auto constSurfNum : surface.ConstituentSurfaceNums) { - QoutAtot += state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(constSurfNum) * state.dataSurface->Surface(constSurfNum).Area; - QinAtot += state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(constSurfNum) * state.dataSurface->Surface(constSurfNum).Area; - Atot += state.dataSurface->Surface(constSurfNum).Area; - } - - state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) = QoutAtot / Atot; - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) = QinAtot / Atot; - } - } - firstSurf = state.dataHeatBal->Zone(zoneNum).WindowSurfaceFirst; - lastSurf = state.dataHeatBal->Zone(zoneNum).WindowSurfaceLast; - for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - auto &surface(state.dataSurface->Surface(surfNum)); - if (surface.ExtSolar && surface.ConstituentSurfaceNums.size() > 1) { + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst; + int lastSurf = thisSpace.OpaqOrIntMassSurfaceLast; + for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { auto &surface(state.dataSurface->Surface(surfNum)); - - // Absorbed in glazing - int totalGlassLayers = state.dataConstruction->Construct(state.dataSurface->SurfActiveConstruction(surfNum)).TotGlassLayers; - for (int layer = 1; layer <= totalGlassLayers; ++layer) { - Real64 QAtot = 0.0; + if (surface.ConstituentSurfaceNums.size() > 1) { + Real64 QoutAtot = 0.0; + Real64 QinAtot = 0.0; Real64 Atot = 0.0; for (auto constSurfNum : surface.ConstituentSurfaceNums) { - QAtot += state.dataHeatBal->SurfWinQRadSWwinAbs(constSurfNum, layer) * state.dataSurface->Surface(constSurfNum).Area; + QoutAtot += state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(constSurfNum) * state.dataSurface->Surface(constSurfNum).Area; + QinAtot += state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(constSurfNum) * state.dataSurface->Surface(constSurfNum).Area; Atot += state.dataSurface->Surface(constSurfNum).Area; } - state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, layer) = QAtot / Atot; + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) = QoutAtot / Atot; + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) = QinAtot / Atot; } - - // Absorbed by frame and dividers - if (surface.FrameDivider > 0) { - if (state.dataSurface->SurfWinFrameArea(surfNum) > 0.0) { - Real64 QoutAtot = 0.0; - Real64 QinAtot = 0.0; + } + firstSurf = thisSpace.WindowSurfaceFirst; + lastSurf = thisSpace.WindowSurfaceLast; + for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { + auto &surface(state.dataSurface->Surface(surfNum)); + if (surface.ExtSolar && surface.ConstituentSurfaceNums.size() > 1) { + auto &surface(state.dataSurface->Surface(surfNum)); + + // Absorbed in glazing + int totalGlassLayers = + state.dataConstruction->Construct(state.dataSurface->SurfActiveConstruction(surfNum)).TotGlassLayers; + for (int layer = 1; layer <= totalGlassLayers; ++layer) { + Real64 QAtot = 0.0; Real64 Atot = 0.0; for (auto constSurfNum : surface.ConstituentSurfaceNums) { - QoutAtot += - state.dataSurface->SurfWinFrameQRadOutAbs(constSurfNum) * state.dataSurface->SurfWinFrameArea(constSurfNum); - QinAtot += - state.dataSurface->SurfWinFrameQRadInAbs(constSurfNum) * state.dataSurface->SurfWinFrameArea(constSurfNum); - Atot += state.dataSurface->SurfWinFrameArea(constSurfNum); + QAtot += + state.dataHeatBal->SurfWinQRadSWwinAbs(constSurfNum, layer) * state.dataSurface->Surface(constSurfNum).Area; + Atot += state.dataSurface->Surface(constSurfNum).Area; } - state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = QoutAtot / Atot; - state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = QinAtot / Atot; + state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, layer) = QAtot / Atot; } - if (state.dataSurface->SurfWinDividerArea(surfNum) > 0.0) { - Real64 QoutAtot = 0.0; - Real64 QinAtot = 0.0; - Real64 Atot = 0.0; - for (auto constSurfNum : surface.ConstituentSurfaceNums) { - QoutAtot += state.dataSurface->SurfWinDividerQRadOutAbs(constSurfNum) * - state.dataSurface->SurfWinDividerArea(constSurfNum); - QinAtot += state.dataSurface->SurfWinDividerQRadInAbs(constSurfNum) * - state.dataSurface->SurfWinDividerArea(constSurfNum); - Atot += state.dataSurface->SurfWinDividerArea(constSurfNum); + + // Absorbed by frame and dividers + if (surface.FrameDivider > 0) { + if (state.dataSurface->SurfWinFrameArea(surfNum) > 0.0) { + Real64 QoutAtot = 0.0; + Real64 QinAtot = 0.0; + Real64 Atot = 0.0; + for (auto constSurfNum : surface.ConstituentSurfaceNums) { + QoutAtot += state.dataSurface->SurfWinFrameQRadOutAbs(constSurfNum) * + state.dataSurface->SurfWinFrameArea(constSurfNum); + QinAtot += state.dataSurface->SurfWinFrameQRadInAbs(constSurfNum) * + state.dataSurface->SurfWinFrameArea(constSurfNum); + Atot += state.dataSurface->SurfWinFrameArea(constSurfNum); + } + + state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = QoutAtot / Atot; + state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = QinAtot / Atot; } + if (state.dataSurface->SurfWinDividerArea(surfNum) > 0.0) { + Real64 QoutAtot = 0.0; + Real64 QinAtot = 0.0; + Real64 Atot = 0.0; + for (auto constSurfNum : surface.ConstituentSurfaceNums) { + QoutAtot += state.dataSurface->SurfWinDividerQRadOutAbs(constSurfNum) * + state.dataSurface->SurfWinDividerArea(constSurfNum); + QinAtot += state.dataSurface->SurfWinDividerQRadInAbs(constSurfNum) * + state.dataSurface->SurfWinDividerArea(constSurfNum); + Atot += state.dataSurface->SurfWinDividerArea(constSurfNum); + } - state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = QoutAtot / Atot; - state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = QinAtot / Atot; + state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = QoutAtot / Atot; + state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = QinAtot / Atot; + } } } } @@ -3732,309 +3759,314 @@ void InitIntSolarDistribution(EnergyPlusData &state) // COMPUTE RADIANT GAINS ON SURFACES for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurfOpaque = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceFirst; - int const lastSurfOpaque = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceLast; - for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) { - int const solEnclosureNum = Surface(SurfNum).SolarEnclIndex; - int const ConstrNum = Surface(SurfNum).Construction; - - Real64 AbsIntSurf = state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum); - // TODO - AbsIntSurfVis = InsideAbsorpSolar instead of InsideAbsorpVis? - Real64 AbsIntSurfVis = - state.dataConstruction->Construct(ConstrNum).InsideAbsorpSolar; // Inside opaque surface visible absorptance to fix CR 8695 change to - - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * AbsIntSurf; - state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(SurfNum) += state.dataHeatBal->EnclSolQSWRadLights(solEnclosureNum) * AbsIntSurfVis; - - // Calculate absorbed solar on outside if movable exterior insulation in place - if (state.dataSurface->AnyMovableInsulation && - state.dataHeatBalSurf->SurfMovInsulExtPresent(SurfNum)) { // Movable outside insulation in place - Real64 AbsExt = state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum); - state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) = - state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) * AbsExt / - state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).AbsorpSolar; - // For transparent insulation, allow some sunlight to get through the movable insulation. - // The equation below is derived by taking what is transmitted through the layer and applying - // the fraction that is absorbed plus the back reflected portion (first order reflection only) - // to the plane between the transparent insulation and the exterior surface face. - state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) = - state.dataMaterial->Material(state.dataSurface->SurfMaterialMovInsulExt(SurfNum)).Trans * - state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) * - ((state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).AbsorpSolar / AbsExt) + - (1 - state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).AbsorpSolar)); - } - // RJH 08/30/07 - Add SurfWinInitialDifSolInAbs, SurfWinInitialDifSolwinAbs, and SurfWinInitialDifSolAbsByShade - // calced in CalcWinTransDifSolInitialDistribution to SurfOpaqQRadSWInAbs, SurfWinQRadSWwinAbs, and SurfWinIntSWAbsByShade here - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(SurfNum); - } // end of opaque - - int const firstSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceFirst; - int const lastSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceLast; - for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { // Window - int const radEnclosureNum = Surface(SurfNum).RadEnclIndex; - int const solEnclosureNum = Surface(SurfNum).SolarEnclIndex; - int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); - - if (state.dataSurface->SurfWinWindowModelType(SurfNum) != WindowModel::EQL) { - int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum); - - int TotGlassLayers = state.dataConstruction->Construct(ConstrNum).TotGlassLayers; - WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum); - - // These calculations are repeated from InitInternalHeatGains for the Zone Component Loads Report - Real64 pulseMultipler = 0.01; // use to create a pulse for the load component report computations, the W/sqft pulse for the zone - if (!state.dataGlobal->doLoadComponentPulseNow) { - state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad * - state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult * - state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum); - } else { - state.dataHeatBalSurfMgr->curQL = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad; - // for the loads component report during the special sizing run increase the radiant portion - // a small amount to create a "pulse" of heat that is used for the - state.dataHeatBalSurfMgr->adjQL = - state.dataHeatBalSurfMgr->curQL + state.dataViewFactor->EnclRadInfo(radEnclosureNum).FloorArea * pulseMultipler; - // ITABSF is the Inside Thermal Absorptance - // EnclRadThermAbsMult is a multiplier for each zone/enclosure - // SurfQdotRadIntGainsInPerArea is the thermal radiation absorbed on inside surfaces - state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) = state.dataHeatBalSurfMgr->adjQL * - state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult * - state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum); + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst; + int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast; + for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) { + int const solEnclosureNum = Surface(SurfNum).SolarEnclIndex; + int const ConstrNum = Surface(SurfNum).Construction; + + Real64 AbsIntSurf = state.dataHeatBalSurf->SurfAbsSolarInt(SurfNum); + // TODO - AbsIntSurfVis = InsideAbsorpSolar instead of InsideAbsorpVis? + Real64 AbsIntSurfVis = state.dataConstruction->Construct(ConstrNum) + .InsideAbsorpSolar; // Inside opaque surface visible absorptance to fix CR 8695 change to + + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * AbsIntSurf; + state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(SurfNum) += state.dataHeatBal->EnclSolQSWRadLights(solEnclosureNum) * AbsIntSurfVis; + + // Calculate absorbed solar on outside if movable exterior insulation in place + if (state.dataSurface->AnyMovableInsulation && + state.dataHeatBalSurf->SurfMovInsulExtPresent(SurfNum)) { // Movable outside insulation in place + Real64 AbsExt = state.dataHeatBalSurf->SurfAbsSolarExt(SurfNum); + state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) = + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) * AbsExt / + state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).AbsorpSolar; + // For transparent insulation, allow some sunlight to get through the movable insulation. + // The equation below is derived by taking what is transmitted through the layer and applying + // the fraction that is absorbed plus the back reflected portion (first order reflection only) + // to the plane between the transparent insulation and the exterior surface face. + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(SurfNum) = + state.dataMaterial->Material(state.dataSurface->SurfMaterialMovInsulExt(SurfNum)).Trans * + state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) * + ((state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).AbsorpSolar / AbsExt) + + (1 - state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).AbsorpSolar)); } + // RJH 08/30/07 - Add SurfWinInitialDifSolInAbs, SurfWinInitialDifSolwinAbs, and SurfWinInitialDifSolAbsByShade + // calced in CalcWinTransDifSolInitialDistribution to SurfOpaqQRadSWInAbs, SurfWinQRadSWwinAbs, and SurfWinIntSWAbsByShade here + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) += state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(SurfNum); + } // end of opaque + + int const firstSurfWin = thisSpace.WindowSurfaceFirst; + int const lastSurfWin = thisSpace.WindowSurfaceLast; + for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { // Window + int const radEnclosureNum = Surface(SurfNum).RadEnclIndex; + int const solEnclosureNum = Surface(SurfNum).SolarEnclIndex; + int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); + + if (state.dataSurface->SurfWinWindowModelType(SurfNum) != WindowModel::EQL) { + int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum); - if (NOT_SHADED(ShadeFlag)) { // No window shading - for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) { - state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += - state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass); + int TotGlassLayers = state.dataConstruction->Construct(ConstrNum).TotGlassLayers; + WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum); + + // These calculations are repeated from InitInternalHeatGains for the Zone Component Loads Report + Real64 pulseMultipler = 0.01; // use to create a pulse for the load component report computations, the W/sqft pulse for the zone + if (!state.dataGlobal->doLoadComponentPulseNow) { + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) = + state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad * + state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum); + } else { + state.dataHeatBalSurfMgr->curQL = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad; + // for the loads component report during the special sizing run increase the radiant portion + // a small amount to create a "pulse" of heat that is used for the + state.dataHeatBalSurfMgr->adjQL = + state.dataHeatBalSurfMgr->curQL + state.dataViewFactor->EnclRadInfo(radEnclosureNum).FloorArea * pulseMultipler; + // ITABSF is the Inside Thermal Absorptance + // EnclRadThermAbsMult is a multiplier for each zone/enclosure + // SurfQdotRadIntGainsInPerArea is the thermal radiation absorbed on inside surfaces + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) = + state.dataHeatBalSurfMgr->adjQL * state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult * + state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum); } - } else if (ConstrNumSh != 0 && ShadeFlag != WinShadingType::SwitchableGlazing) { - // Interior, exterior or between-glass shade, screen or blind in place - for (int IGlass = 1; IGlass <= state.dataConstruction->Construct(ConstrNumSh).TotGlassLayers; ++IGlass) { - if (ANY_SHADE_SCREEN(ShadeFlag)) { + + if (NOT_SHADED(ShadeFlag)) { // No window shading + for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) { state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += - state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * - state.dataConstruction->Construct(ConstrNumSh).AbsDiffBack(IGlass); - } else if (BITF_TEST_ANY(BITF(ShadeFlag), BITF(WinShadingType::IntBlind) | BITF(WinShadingType::ExtBlind))) { - Real64 BlAbsDiffBk; // Glass layer back diffuse solar absorptance when blind in place + state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass); + } + } else if (ConstrNumSh != 0 && ShadeFlag != WinShadingType::SwitchableGlazing) { + // Interior, exterior or between-glass shade, screen or blind in place + for (int IGlass = 1; IGlass <= state.dataConstruction->Construct(ConstrNumSh).TotGlassLayers; ++IGlass) { + if (ANY_SHADE_SCREEN(ShadeFlag)) { + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += + state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * + state.dataConstruction->Construct(ConstrNumSh).AbsDiffBack(IGlass); + } else if (BITF_TEST_ANY(BITF(ShadeFlag), BITF(WinShadingType::IntBlind) | BITF(WinShadingType::ExtBlind))) { + Real64 BlAbsDiffBk; // Glass layer back diffuse solar absorptance when blind in place + if (state.dataSurface->SurfWinMovableSlats(SurfNum)) { + BlAbsDiffBk = General::InterpGeneral( + state.dataConstruction->Construct(ConstrNumSh) + .BlAbsDiffBack(state.dataSurface->SurfWinSlatsAngIndex(SurfNum), IGlass), + state.dataConstruction->Construct(ConstrNumSh) + .BlAbsDiffBack(std::min(MaxSlatAngs, state.dataSurface->SurfWinSlatsAngIndex(SurfNum) + 1), IGlass), + state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum)); + } else { + BlAbsDiffBk = state.dataConstruction->Construct(ConstrNumSh).BlAbsDiffBack(1, IGlass); + } + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += + state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * BlAbsDiffBk; + } + } + if (ShadeFlag == WinShadingType::IntShade) { + state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad * + state.dataConstruction->Construct(ConstrNumSh).ShadeAbsorpThermal * + state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult; + } else if (ShadeFlag == WinShadingType::IntBlind) { + Real64 EffBlEmiss; // Blind emissivity (thermal absorptance) as part of glazing system if (state.dataSurface->SurfWinMovableSlats(SurfNum)) { - BlAbsDiffBk = General::InterpGeneral( - state.dataConstruction->Construct(ConstrNumSh) - .BlAbsDiffBack(state.dataSurface->SurfWinSlatsAngIndex(SurfNum), IGlass), - state.dataConstruction->Construct(ConstrNumSh) - .BlAbsDiffBack(std::min(MaxSlatAngs, state.dataSurface->SurfWinSlatsAngIndex(SurfNum) + 1), IGlass), + EffBlEmiss = General::InterpGeneral( + state.dataSurface->SurfaceWindow(SurfNum).EffShBlindEmiss(state.dataSurface->SurfWinSlatsAngIndex(SurfNum)), + state.dataSurface->SurfaceWindow(SurfNum).EffShBlindEmiss( + std::min(MaxSlatAngs, state.dataSurface->SurfWinSlatsAngIndex(SurfNum) + 1)), state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum)); } else { - BlAbsDiffBk = state.dataConstruction->Construct(ConstrNumSh).BlAbsDiffBack(1, IGlass); + EffBlEmiss = state.dataSurface->SurfaceWindow(SurfNum).EffShBlindEmiss(1); } - state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += - state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * BlAbsDiffBk; + state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad * + EffBlEmiss * + state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult; } - } - if (ShadeFlag == WinShadingType::IntShade) { - state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad * - state.dataConstruction->Construct(ConstrNumSh).ShadeAbsorpThermal * - state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult; - } else if (ShadeFlag == WinShadingType::IntBlind) { - Real64 EffBlEmiss; // Blind emissivity (thermal absorptance) as part of glazing system - if (state.dataSurface->SurfWinMovableSlats(SurfNum)) { - EffBlEmiss = General::InterpGeneral( - state.dataSurface->SurfaceWindow(SurfNum).EffShBlindEmiss(state.dataSurface->SurfWinSlatsAngIndex(SurfNum)), - state.dataSurface->SurfaceWindow(SurfNum).EffShBlindEmiss( - std::min(MaxSlatAngs, state.dataSurface->SurfWinSlatsAngIndex(SurfNum) + 1)), - state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum)); - } else { - EffBlEmiss = state.dataSurface->SurfaceWindow(SurfNum).EffShBlindEmiss(1); + if (ANY_SHADE_SCREEN(ShadeFlag)) { + state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) = + state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * state.dataConstruction->Construct(ConstrNumSh).AbsDiffBackShade; + } else if (ANY_BLIND(ShadeFlag)) { + Real64 AbsDiffBkBl; + if (state.dataSurface->SurfWinMovableSlats(SurfNum)) { + AbsDiffBkBl = General::InterpGeneral( + state.dataConstruction->Construct(ConstrNumSh).AbsDiffBackBlind(state.dataSurface->SurfWinSlatsAngIndex(SurfNum)), + state.dataConstruction->Construct(ConstrNumSh) + .AbsDiffBackBlind(std::min(MaxSlatAngs, state.dataSurface->SurfWinSlatsAngIndex(SurfNum) + 1)), + state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum)); + } else { + AbsDiffBkBl = state.dataConstruction->Construct(ConstrNumSh).AbsDiffBackBlind(1); + } + state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) = state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * AbsDiffBkBl; } - state.dataSurface->SurfWinIntLWAbsByShade(SurfNum) = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad * - EffBlEmiss * - state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult; - } - if (ANY_SHADE_SCREEN(ShadeFlag)) { - state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) = - state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * state.dataConstruction->Construct(ConstrNumSh).AbsDiffBackShade; - } else if (ANY_BLIND(ShadeFlag)) { - Real64 AbsDiffBkBl; - if (state.dataSurface->SurfWinMovableSlats(SurfNum)) { - AbsDiffBkBl = General::InterpGeneral( - state.dataConstruction->Construct(ConstrNumSh).AbsDiffBackBlind(state.dataSurface->SurfWinSlatsAngIndex(SurfNum)), - state.dataConstruction->Construct(ConstrNumSh) - .AbsDiffBackBlind(std::min(MaxSlatAngs, state.dataSurface->SurfWinSlatsAngIndex(SurfNum) + 1)), - state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum)); - } else { - AbsDiffBkBl = state.dataConstruction->Construct(ConstrNumSh).AbsDiffBackBlind(1); + // Correct for divider shadowing + if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) { + state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) *= state.dataSurface->SurfWinGlazedFrac(SurfNum); } - state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) = state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * AbsDiffBkBl; - } - // Correct for divider shadowing - if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(ShadeFlag)) { - state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) *= state.dataSurface->SurfWinGlazedFrac(SurfNum); - } - } else if (ShadeFlag == WinShadingType::SwitchableGlazing) { // Switchable glazing - for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) { + } else if (ShadeFlag == WinShadingType::SwitchableGlazing) { // Switchable glazing + for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) { - state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += - state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * - InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum), - state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass), - state.dataConstruction->Construct(ConstrNumSh).AbsDiffBack(IGlass)); - } + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += + state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * + InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum), + state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass), + state.dataConstruction->Construct(ConstrNumSh).AbsDiffBack(IGlass)); + } - } // End of shading flag check - - // Note that FrameQRadInAbs is initially calculated in InitSolarHeatGains - if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) - state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) += - (state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum) + - (state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad * - state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult + - state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)) * - state.dataSurface->SurfWinFrameEmis(SurfNum)) * - (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum)); // Window has a frame - if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) { // Window has dividers - Real64 DividerThermAbs = state.dataSurface->SurfWinDividerEmis(SurfNum); // Window divider thermal absorptance - Real64 DividerSolAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance - if (state.dataSurface->SurfWinDividerType(SurfNum) == - DataSurfaces::FrameDividerType::Suspended) { // Suspended divider; account for inside glass - Real64 MatNumGl = state.dataConstruction->Construct(ConstrNum).LayerPoint( - state.dataConstruction->Construct(ConstrNum).TotLayers); // Glass layer material number - Real64 TransGl = state.dataMaterial->Material(MatNumGl).Trans; // Glass layer solar transmittance, reflectance, absorptance - Real64 ReflGl = state.dataMaterial->Material(MatNumGl).ReflectSolBeamBack; - Real64 AbsGl = 1.0 - TransGl - ReflGl; - Real64 DividerSolRefl = 1.0 - DividerSolAbs; // Window divider solar reflectance - DividerSolAbs = AbsGl + TransGl * (DividerSolAbs + DividerSolRefl * AbsGl) / (1.0 - DividerSolRefl * ReflGl); - DividerThermAbs = state.dataMaterial->Material(MatNumGl).AbsorpThermalBack; - } - // Correct for interior shade transmittance - if (ShadeFlag == WinShadingType::IntShade) { - int MatNumSh = state.dataConstruction->Construct(ConstrNumSh) - .LayerPoint(state.dataConstruction->Construct(ConstrNumSh).TotLayers); // Shade layer material number - DividerSolAbs *= state.dataMaterial->Material(MatNumSh).Trans; - DividerThermAbs *= state.dataMaterial->Material(MatNumSh).TransThermal; - } else if (ShadeFlag == WinShadingType::IntBlind) { - int BlNum = state.dataSurface->SurfWinBlindNumber(SurfNum); - Real64 SolBackDiffDiffTrans; - Real64 IRBackTrans; - if (state.dataSurface->SurfWinMovableSlats(SurfNum)) { - int SurfWinSlatsAngIndex = state.dataSurface->SurfWinSlatsAngIndex(SurfNum); - Real64 SurfWinSlatsAngInterpFac = state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum); - SolBackDiffDiffTrans = General::InterpGeneral( - state.dataHeatBal->Blind(BlNum).SolBackDiffDiffTrans(SurfWinSlatsAngIndex), - state.dataHeatBal->Blind(BlNum).SolBackDiffDiffTrans(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)), - SurfWinSlatsAngInterpFac); - IRBackTrans = - General::InterpGeneral(state.dataHeatBal->Blind(BlNum).IRBackTrans(SurfWinSlatsAngIndex), - state.dataHeatBal->Blind(BlNum).IRBackTrans(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)), - SurfWinSlatsAngInterpFac); - } else { - SolBackDiffDiffTrans = state.dataHeatBal->Blind(BlNum).SolBackDiffDiffTrans(1); - IRBackTrans = state.dataHeatBal->Blind(BlNum).IRBackTrans(1); + } // End of shading flag check + + // Note that FrameQRadInAbs is initially calculated in InitSolarHeatGains + if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) + state.dataSurface->SurfWinFrameQRadInAbs(SurfNum) += + (state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * state.dataSurface->SurfWinFrameSolAbsorp(SurfNum) + + (state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad * + state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult + + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)) * + state.dataSurface->SurfWinFrameEmis(SurfNum)) * + (1.0 + 0.5 * state.dataSurface->SurfWinProjCorrFrIn(SurfNum)); // Window has a frame + if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0) { // Window has dividers + Real64 DividerThermAbs = state.dataSurface->SurfWinDividerEmis(SurfNum); // Window divider thermal absorptance + Real64 DividerSolAbs = state.dataSurface->SurfWinDividerSolAbsorp(SurfNum); // Window divider solar absorptance + if (state.dataSurface->SurfWinDividerType(SurfNum) == + DataSurfaces::FrameDividerType::Suspended) { // Suspended divider; account for inside glass + Real64 MatNumGl = state.dataConstruction->Construct(ConstrNum).LayerPoint( + state.dataConstruction->Construct(ConstrNum).TotLayers); // Glass layer material number + Real64 TransGl = + state.dataMaterial->Material(MatNumGl).Trans; // Glass layer solar transmittance, reflectance, absorptance + Real64 ReflGl = state.dataMaterial->Material(MatNumGl).ReflectSolBeamBack; + Real64 AbsGl = 1.0 - TransGl - ReflGl; + Real64 DividerSolRefl = 1.0 - DividerSolAbs; // Window divider solar reflectance + DividerSolAbs = AbsGl + TransGl * (DividerSolAbs + DividerSolRefl * AbsGl) / (1.0 - DividerSolRefl * ReflGl); + DividerThermAbs = state.dataMaterial->Material(MatNumGl).AbsorpThermalBack; + } + // Correct for interior shade transmittance + if (ShadeFlag == WinShadingType::IntShade) { + int MatNumSh = state.dataConstruction->Construct(ConstrNumSh) + .LayerPoint(state.dataConstruction->Construct(ConstrNumSh).TotLayers); // Shade layer material number + DividerSolAbs *= state.dataMaterial->Material(MatNumSh).Trans; + DividerThermAbs *= state.dataMaterial->Material(MatNumSh).TransThermal; + } else if (ShadeFlag == WinShadingType::IntBlind) { + int BlNum = state.dataSurface->SurfWinBlindNumber(SurfNum); + Real64 SolBackDiffDiffTrans; + Real64 IRBackTrans; + if (state.dataSurface->SurfWinMovableSlats(SurfNum)) { + int SurfWinSlatsAngIndex = state.dataSurface->SurfWinSlatsAngIndex(SurfNum); + Real64 SurfWinSlatsAngInterpFac = state.dataSurface->SurfWinSlatsAngInterpFac(SurfNum); + SolBackDiffDiffTrans = General::InterpGeneral( + state.dataHeatBal->Blind(BlNum).SolBackDiffDiffTrans(SurfWinSlatsAngIndex), + state.dataHeatBal->Blind(BlNum).SolBackDiffDiffTrans(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)), + SurfWinSlatsAngInterpFac); + IRBackTrans = General::InterpGeneral( + state.dataHeatBal->Blind(BlNum).IRBackTrans(SurfWinSlatsAngIndex), + state.dataHeatBal->Blind(BlNum).IRBackTrans(std::min(MaxSlatAngs, SurfWinSlatsAngIndex + 1)), + SurfWinSlatsAngInterpFac); + } else { + SolBackDiffDiffTrans = state.dataHeatBal->Blind(BlNum).SolBackDiffDiffTrans(1); + IRBackTrans = state.dataHeatBal->Blind(BlNum).IRBackTrans(1); + } + DividerSolAbs *= SolBackDiffDiffTrans; + DividerThermAbs *= IRBackTrans; } - DividerSolAbs *= SolBackDiffDiffTrans; - DividerThermAbs *= IRBackTrans; + // Note that DividerQRadInAbs is initially calculated in InitSolarHeatGains + state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) += + (state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * DividerSolAbs + + (state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad * + state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult + + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)) * + DividerThermAbs) * + (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)); } - // Note that DividerQRadInAbs is initially calculated in InitSolarHeatGains - state.dataSurface->SurfWinDividerQRadInAbs(SurfNum) += (state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * DividerSolAbs + - (state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad * - state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult + - state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(SurfNum)) * - DividerThermAbs) * - (1.0 + state.dataSurface->SurfWinProjCorrDivIn(SurfNum)); - } - } else { - // These calculations are repeated from InitInternalHeatGains for the Zone Component Loads Report - Real64 pulseMultipler = 0.01; // the W/sqft pulse for the zone - if (!state.dataGlobal->doLoadComponentPulseNow) { - state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad * - state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult * - state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum); } else { - state.dataHeatBalSurfMgr->curQL = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad; - // for the loads component report during the special sizing run increase the radiant portion - // a small amount to create a "pulse" of heat that is used for the - state.dataHeatBalSurfMgr->adjQL = - state.dataHeatBalSurfMgr->curQL + state.dataViewFactor->EnclRadInfo(radEnclosureNum).FloorArea * pulseMultipler; - // ITABSF is the Inside Thermal Absorptance - // EnclRadThermAbsMult is a multiplier for each zone/radiant enclosure - // SurfQdotRadIntGainsInPerArea is the thermal radiation absorbed on inside surfaces - state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) = state.dataHeatBalSurfMgr->adjQL * - state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult * - state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum); - } - // Radiations absorbed by the window layers coming from zone side - int EQLNum = state.dataConstruction->Construct(ConstrNum).EQLConsPtr; - for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) { - state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) += - state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * state.dataConstruction->Construct(ConstrNum).AbsDiffBackEQL(Lay); - } - // Window frame has not been included for equivalent layer model yet - - } // end if for IF ( SurfaceWindow(SurfNum)%WindowModelType /= WindowModel:: EQL) THEN - - if (Surface(SurfNum).ExtBoundCond > 0) { // Interzone surface - // Short-wave radiation absorbed in panes of corresponding window in adjacent zone - int SurfNumAdjZone = Surface(SurfNum).ExtBoundCond; // Surface number in adjacent zone for interzone surfaces - if (state.dataSurface->SurfWinWindowModelType(SurfNumAdjZone) != WindowModel::EQL) { - int TotGlassLayers = state.dataConstruction->Construct(ConstrNum).TotGlassLayers; - for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) { - state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNumAdjZone, IGlass) += - state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * - state.dataConstruction->Construct(Surface(SurfNumAdjZone).Construction).AbsDiff(IGlass); - // Note that AbsDiff rather than AbsDiffBack is used in the above since the - // radiation from the current zone is incident on the outside of the adjacent - // zone's window. + // These calculations are repeated from InitInternalHeatGains for the Zone Component Loads Report + Real64 pulseMultipler = 0.01; // the W/sqft pulse for the zone + if (!state.dataGlobal->doLoadComponentPulseNow) { + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) = + state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad * + state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum); + } else { + state.dataHeatBalSurfMgr->curQL = state.dataViewFactor->EnclRadInfo(radEnclosureNum).radQThermalRad; + // for the loads component report during the special sizing run increase the radiant portion + // a small amount to create a "pulse" of heat that is used for the + state.dataHeatBalSurfMgr->adjQL = + state.dataHeatBalSurfMgr->curQL + state.dataViewFactor->EnclRadInfo(radEnclosureNum).FloorArea * pulseMultipler; + // ITABSF is the Inside Thermal Absorptance + // EnclRadThermAbsMult is a multiplier for each zone/radiant enclosure + // SurfQdotRadIntGainsInPerArea is the thermal radiation absorbed on inside surfaces + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) = + state.dataHeatBalSurfMgr->adjQL * state.dataViewFactor->EnclRadInfo(radEnclosureNum).radThermAbsMult * + state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum); } - } else { // IF (SurfaceWindow(SurfNumAdjZone)%WindowModelType == WindowModel:: EQL) THEN - int const AdjConstrNum = Surface(SurfNumAdjZone).Construction; - int const EQLNum = state.dataConstruction->Construct(AdjConstrNum).EQLConsPtr; + // Radiations absorbed by the window layers coming from zone side + int EQLNum = state.dataConstruction->Construct(ConstrNum).EQLConsPtr; for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) { - state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNumAdjZone, Lay) += - state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * state.dataConstruction->Construct(ConstrNum).AbsDiffFrontEQL(Lay); - // Note that AbsDiffFrontEQL rather than AbsDiffBackEQL is used in the above - // since the radiation from the current zone is incident on the outside of the - // adjacent zone's window. + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) += + state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * state.dataConstruction->Construct(ConstrNum).AbsDiffBackEQL(Lay); } - } - } + // Window frame has not been included for equivalent layer model yet - if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::Detailed) { - int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum); - int TotGlassLayers = state.dataConstruction->Construct(ConstrNum).TotGlassLayers; - WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum); - if (NOT_SHADED(ShadeFlag)) { // No window shading - for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) { - state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass); + } // end if for IF ( SurfaceWindow(SurfNum)%WindowModelType /= WindowModel:: EQL) THEN + + if (Surface(SurfNum).ExtBoundCond > 0) { // Interzone surface + // Short-wave radiation absorbed in panes of corresponding window in adjacent zone + int SurfNumAdjZone = Surface(SurfNum).ExtBoundCond; // Surface number in adjacent zone for interzone surfaces + if (state.dataSurface->SurfWinWindowModelType(SurfNumAdjZone) != WindowModel::EQL) { + int TotGlassLayers = state.dataConstruction->Construct(ConstrNum).TotGlassLayers; + for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) { + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNumAdjZone, IGlass) += + state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * + state.dataConstruction->Construct(Surface(SurfNumAdjZone).Construction).AbsDiff(IGlass); + // Note that AbsDiff rather than AbsDiffBack is used in the above since the + // radiation from the current zone is incident on the outside of the adjacent + // zone's window. + } + } else { // IF (SurfaceWindow(SurfNumAdjZone)%WindowModelType == WindowModel:: EQL) THEN + int const AdjConstrNum = Surface(SurfNumAdjZone).Construction; + int const EQLNum = state.dataConstruction->Construct(AdjConstrNum).EQLConsPtr; + for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) { + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNumAdjZone, Lay) += + state.dataHeatBal->EnclSolQSWRad(solEnclosureNum) * state.dataConstruction->Construct(ConstrNum).AbsDiffFrontEQL(Lay); + // Note that AbsDiffFrontEQL rather than AbsDiffBackEQL is used in the above + // since the radiation from the current zone is incident on the outside of the + // adjacent zone's window. + } } - } else if (ShadeFlag == WinShadingType::SwitchableGlazing) { // Switchable glazing + } + + if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::Detailed) { + int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum); + int TotGlassLayers = state.dataConstruction->Construct(ConstrNum).TotGlassLayers; + WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum); + if (NOT_SHADED(ShadeFlag)) { // No window shading + for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) { + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass); + } + } else if (ShadeFlag == WinShadingType::SwitchableGlazing) { // Switchable glazing + for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) { + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass); + } + } else { + // Interior, exterior or between-glass shade, screen or blind in place + for (int IGlass = 1; IGlass <= state.dataConstruction->Construct(ConstrNumSh).TotGlassLayers; ++IGlass) { + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass); + } + if (ANY_SHADE_SCREEN(ShadeFlag)) { + state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) += state.dataSurface->SurfWinInitialDifSolAbsByShade(SurfNum); + } else if (ANY_BLIND(ShadeFlag)) { + state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) += state.dataSurface->SurfWinInitialDifSolAbsByShade(SurfNum); + } + } // End of shading flag check + } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) { + int TotGlassLayers = state.dataConstruction->Construct(ConstrNum).TotGlassLayers; for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) { state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass); } - } else { - // Interior, exterior or between-glass shade, screen or blind in place - for (int IGlass = 1; IGlass <= state.dataConstruction->Construct(ConstrNumSh).TotGlassLayers; ++IGlass) { - state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass); - } - if (ANY_SHADE_SCREEN(ShadeFlag)) { - state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) += state.dataSurface->SurfWinInitialDifSolAbsByShade(SurfNum); - } else if (ANY_BLIND(ShadeFlag)) { - state.dataSurface->SurfWinIntSWAbsByShade(SurfNum) += state.dataSurface->SurfWinInitialDifSolAbsByShade(SurfNum); - } - } // End of shading flag check - } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) { - int TotGlassLayers = state.dataConstruction->Construct(ConstrNum).TotGlassLayers; - for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) { - state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, IGlass) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, IGlass); - } - } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::EQL) { + } else if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::EQL) { - // ConstrNum = Surface(SurfNum)%Construction - int EQLNum = state.dataConstruction->Construct(ConstrNum).EQLConsPtr; + // ConstrNum = Surface(SurfNum)%Construction + int EQLNum = state.dataConstruction->Construct(ConstrNum).EQLConsPtr; - for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) { - state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, Lay); + for (int Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) { + state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum, Lay) += state.dataHeatBal->SurfWinInitialDifSolwinAbs(SurfNum, Lay); + } } - } - } // End of window + } // End of window + } } DistributeTDDAbsorbedSolar(state); } @@ -4060,21 +4092,20 @@ void ComputeIntThermalAbsorpFactors(EnergyPlusData &state) for (auto &thisEnclosure : state.dataViewFactor->EnclRadInfo) { if (!thisEnclosure.radReCalc) continue; - // MJW TODO: When surface sort by space merges in this can revert to looping over window surfaces only - // for (int spaceNum : thisEnclosure.spaceNums) { - // auto &thisSpace = state.dataHeatBal->space(spaceNum); - // int const firstSurfWin = thisSpace.WindowSurfaceFirst; - // int const lastSurfWin = thisSpace.WindowSurfaceLast; - for (int const SurfNum : thisEnclosure.SurfacePtr) { - if (state.dataSurface->Surface(SurfNum).Class != DataSurfaces::SurfaceClass::Window) continue; - WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum); - if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) { - Real64 BlindEmiss = state.dataSurface->SurfaceWindow(SurfNum).EffShBlindEmiss(1); - Real64 GlassEmiss = state.dataSurface->SurfaceWindow(SurfNum).EffGlassEmiss(1); - state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = BlindEmiss + GlassEmiss; - } else { - int ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); - state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = state.dataConstruction->Construct(ConstrNum).InsideAbsorpThermal; + for (int spaceNum : thisEnclosure.spaceNums) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurfWin = thisSpace.WindowSurfaceFirst; + int const lastSurfWin = thisSpace.WindowSurfaceLast; + for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { + WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum); + if (ANY_INTERIOR_SHADE_BLIND(ShadeFlag)) { + Real64 BlindEmiss = state.dataSurface->SurfaceWindow(SurfNum).EffShBlindEmiss(1); + Real64 GlassEmiss = state.dataSurface->SurfaceWindow(SurfNum).EffGlassEmiss(1); + state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = BlindEmiss + GlassEmiss; + } else { + int ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); + state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) = state.dataConstruction->Construct(ConstrNum).InsideAbsorpThermal; + } } } } @@ -4166,10 +4197,9 @@ void ComputeIntThermalAbsorpFactors(EnergyPlusData &state) } } // End of loop over surfaces in zone/enclosure - thisRadEnclosure.radThermAbsMult = 1.0 / SUM1; - } // End of loop over zones + } // End of loop over enclosures } void ComputeIntSWAbsorpFactors(EnergyPlusData &state) @@ -4794,20 +4824,25 @@ void UpdateIntermediateSurfaceHeatBalanceResults(EnergyPlusData &state, Optional } for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) { - int const firstSurf = state.dataHeatBal->Zone(zoneNum).WindowSurfaceFirst; - int const lastSurf = state.dataHeatBal->Zone(zoneNum).WindowSurfaceLast; - for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - if (state.dataSurface->Surface(surfNum).ExtSolar) { // WindowManager's definition of ZoneWinHeatGain/Loss - state.dataHeatBal->ZoneWinHeatGain(zoneNum) += state.dataSurface->SurfWinHeatGain(surfNum); + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurf = thisSpace.WindowSurfaceFirst; + int const lastSurf = thisSpace.WindowSurfaceLast; + for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { + if (state.dataSurface->Surface(surfNum).ExtSolar) { // WindowManager's definition of ZoneWinHeatGain/Loss + state.dataHeatBal->ZoneWinHeatGain(zoneNum) += state.dataSurface->SurfWinHeatGain(surfNum); + } + } + // Update zone window heat gain reports (these intermediate values are also used for Sensible Heat Gain Summary in GatherHeatGainReport) + if (state.dataHeatBal->ZoneWinHeatGain(zoneNum) >= 0.0) { + state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) = state.dataHeatBal->ZoneWinHeatGain(zoneNum); + state.dataHeatBal->ZoneWinHeatGainRepEnergy(zoneNum) = + state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec; + } else { + state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) = -state.dataHeatBal->ZoneWinHeatGain(zoneNum); + state.dataHeatBal->ZoneWinHeatLossRepEnergy(zoneNum) = + state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec; } - } - // Update zone window heat gain reports (these intermediate values are also used for Sensible Heat Gain Summary in GatherHeatGainReport) - if (state.dataHeatBal->ZoneWinHeatGain(zoneNum) >= 0.0) { - state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) = state.dataHeatBal->ZoneWinHeatGain(zoneNum); - state.dataHeatBal->ZoneWinHeatGainRepEnergy(zoneNum) = state.dataHeatBal->ZoneWinHeatGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec; - } else { - state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) = -state.dataHeatBal->ZoneWinHeatGain(zoneNum); - state.dataHeatBal->ZoneWinHeatLossRepEnergy(zoneNum) = state.dataHeatBal->ZoneWinHeatLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec; } } @@ -4819,21 +4854,27 @@ void UpdateIntermediateSurfaceHeatBalanceResults(EnergyPlusData &state, Optional // Opaque or window surfaces (Skip TDD:DOME objects. Inside temp is handled by TDD:DIFFUSER.) for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) { - int const firstSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrWinSurfaceFirst; - int const lastSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrWinSurfaceLast; - for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum) = - -state.dataHeatBalSurf->SurfHConvInt(surfNum) * - (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum)); + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst; + int const lastSurf = thisSpace.OpaqOrWinSurfaceLast; + for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { + state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum) = + -state.dataHeatBalSurf->SurfHConvInt(surfNum) * + (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum)); + } } } // Opaque surfaces for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) { - int const firstSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceFirst; - int const lastSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceLast; - for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(surfNum) = - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) - state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum); + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst; + int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast; + for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { + state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(surfNum) = + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) - state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum); + } } } // Inside face conduction calculation for Kiva surfaces @@ -4856,14 +4897,16 @@ void UpdateNonRepresentativeSurfaceResults(EnergyPlusData &state, Optional_int_c } for (int zoneNum = firstZone; zoneNum <= lastZone; ++zoneNum) { - // Heat transfer surfaces - int firstSurf = state.dataHeatBal->Zone(zoneNum).HTSurfaceFirst; - int lastSurf = state.dataHeatBal->Zone(zoneNum).HTSurfaceLast; - for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - auto &surface(state.dataSurface->Surface(surfNum)); - int repSurfNum = surface.RepresentativeCalcSurfNum; - - if (surfNum != repSurfNum) { + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + // Heat transfer surfaces + int firstSurf = thisSpace.HTSurfaceFirst; + int lastSurf = thisSpace.HTSurfaceLast; + for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { + auto &surface(state.dataSurface->Surface(surfNum)); + int repSurfNum = surface.RepresentativeCalcSurfNum; + + if (surfNum != repSurfNum) { #if 0 // Check for divergence Real64 surfConv = -state.dataHeatBalSurf->SurfHConvInt(surfNum) * @@ -4898,97 +4941,100 @@ void UpdateNonRepresentativeSurfaceResults(EnergyPlusData &state, Optional_int_c } #endif - // Surface Heat Balance Arrays - state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempIn(repSurfNum); - state.dataHeatBalSurf->SurfTempOut(surfNum) = state.dataHeatBalSurf->SurfTempOut(repSurfNum); - state.dataHeatBal->SurfTempEffBulkAir(surfNum) = state.dataHeatBal->SurfTempEffBulkAir(repSurfNum); - state.dataHeatBalSurf->SurfHConvInt(surfNum) = state.dataHeatBalSurf->SurfHConvInt(repSurfNum); - state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(repSurfNum); - state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) = state.dataHeatBal->SurfQdotRadIntGainsInPerArea(repSurfNum); - state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(repSurfNum); - - state.dataHeatBalSurf->SurfQdotConvOutPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotConvOutPerArea(repSurfNum); - state.dataHeatBalSurf->SurfHcExt(surfNum) = state.dataHeatBalSurf->SurfHcExt(repSurfNum); - state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(repSurfNum); - state.dataHeatBalSurf->SurfHAirExt(surfNum) = state.dataHeatBalSurf->SurfHAirExt(repSurfNum); - state.dataHeatBalSurf->SurfHSkyExt(surfNum) = state.dataHeatBalSurf->SurfHSkyExt(repSurfNum); - state.dataHeatBalSurf->SurfHGrdExt(surfNum) = state.dataHeatBalSurf->SurfHGrdExt(repSurfNum); - - state.dataSurface->SurfTAirRef(surfNum) = state.dataSurface->SurfTAirRef(repSurfNum); - if (state.dataSurface->SurfTAirRef(surfNum) != DataSurfaces::RefAirTemp::Invalid) { - state.dataSurface->SurfTAirRefRpt(surfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(surfNum)]; - } + // Surface Heat Balance Arrays + state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempIn(repSurfNum); + state.dataHeatBalSurf->SurfTempOut(surfNum) = state.dataHeatBalSurf->SurfTempOut(repSurfNum); + state.dataHeatBal->SurfTempEffBulkAir(surfNum) = state.dataHeatBal->SurfTempEffBulkAir(repSurfNum); + state.dataHeatBalSurf->SurfHConvInt(surfNum) = state.dataHeatBalSurf->SurfHConvInt(repSurfNum); + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(repSurfNum); + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) = state.dataHeatBal->SurfQdotRadIntGainsInPerArea(repSurfNum); + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(repSurfNum); + + state.dataHeatBalSurf->SurfQdotConvOutPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotConvOutPerArea(repSurfNum); + state.dataHeatBalSurf->SurfHcExt(surfNum) = state.dataHeatBalSurf->SurfHcExt(repSurfNum); + state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(repSurfNum); + state.dataHeatBalSurf->SurfHAirExt(surfNum) = state.dataHeatBalSurf->SurfHAirExt(repSurfNum); + state.dataHeatBalSurf->SurfHSkyExt(surfNum) = state.dataHeatBalSurf->SurfHSkyExt(repSurfNum); + state.dataHeatBalSurf->SurfHGrdExt(surfNum) = state.dataHeatBalSurf->SurfHGrdExt(repSurfNum); + + state.dataSurface->SurfTAirRef(surfNum) = state.dataSurface->SurfTAirRef(repSurfNum); + if (state.dataSurface->SurfTAirRef(surfNum) != DataSurfaces::RefAirTemp::Invalid) { + state.dataSurface->SurfTAirRefRpt(surfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(surfNum)]; + } - state.dataSurface->SurfOutConvHfModelEq(surfNum) = state.dataSurface->SurfOutConvHfModelEq(repSurfNum); - state.dataSurface->SurfOutConvHnModelEq(surfNum) = state.dataSurface->SurfOutConvHnModelEq(repSurfNum); + state.dataSurface->SurfOutConvHfModelEq(surfNum) = state.dataSurface->SurfOutConvHfModelEq(repSurfNum); + state.dataSurface->SurfOutConvHnModelEq(surfNum) = state.dataSurface->SurfOutConvHnModelEq(repSurfNum); - state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) = state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(repSurfNum); - state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(surfNum) = - state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(repSurfNum); + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) = + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(repSurfNum); + state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(surfNum) = + state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(repSurfNum); - // Internal (non reporting variables) - state.dataHeatBalSurf->SurfTempInTmp(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(repSurfNum); - state.dataHeatBalSurfMgr->RefAirTemp(surfNum) = state.dataHeatBalSurfMgr->RefAirTemp(repSurfNum); + // Internal (non reporting variables) + state.dataHeatBalSurf->SurfTempInTmp(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(repSurfNum); + state.dataHeatBalSurfMgr->RefAirTemp(surfNum) = state.dataHeatBalSurfMgr->RefAirTemp(repSurfNum); + } } - } - // Opaque surfaces - firstSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceFirst; - lastSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceLast; - for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - auto &surface(state.dataSurface->Surface(surfNum)); - int repSurfNum = surface.RepresentativeCalcSurfNum; + // Opaque surfaces + firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst; + lastSurf = thisSpace.OpaqOrIntMassSurfaceLast; + for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { + auto &surface(state.dataSurface->Surface(surfNum)); + int repSurfNum = surface.RepresentativeCalcSurfNum; - if (surfNum != repSurfNum) { - // Surface Heat Balance Arrays - state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(repSurfNum); - state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(repSurfNum); - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(repSurfNum); + if (surfNum != repSurfNum) { + // Surface Heat Balance Arrays + state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum) = state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(repSurfNum); + state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(repSurfNum); + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(repSurfNum); + } } - } - // Window surfaces - firstSurf = state.dataHeatBal->Zone(zoneNum).WindowSurfaceFirst; - lastSurf = state.dataHeatBal->Zone(zoneNum).WindowSurfaceLast; - for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - auto &surface(state.dataSurface->Surface(surfNum)); - int repSurfNum = surface.RepresentativeCalcSurfNum; + // Window surfaces + firstSurf = thisSpace.WindowSurfaceFirst; + lastSurf = thisSpace.WindowSurfaceLast; + for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { + auto &surface(state.dataSurface->Surface(surfNum)); + int repSurfNum = surface.RepresentativeCalcSurfNum; - if (surfNum != repSurfNum) { - auto areaRatio = surface.Area / state.dataSurface->Surface(surfNum).Area; + if (surfNum != repSurfNum) { + auto areaRatio = surface.Area / state.dataSurface->Surface(surfNum).Area; - // Glazing - state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) = state.dataSurface->SurfWinGainConvGlazToZoneRep(repSurfNum) * areaRatio; - state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = state.dataSurface->SurfWinGainIRGlazToZoneRep(repSurfNum) * areaRatio; + // Glazing + state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) = + state.dataSurface->SurfWinGainConvGlazToZoneRep(repSurfNum) * areaRatio; + state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = state.dataSurface->SurfWinGainIRGlazToZoneRep(repSurfNum) * areaRatio; - // Frame - Real64 frameHeatGain = 0.0; - if (state.dataSurface->SurfWinFrameArea(surfNum) > 0.0) { - auto frameAreaRatio = state.dataSurface->SurfWinFrameArea(surfNum) / state.dataSurface->SurfWinFrameArea(repSurfNum); - state.dataSurface->SurfWinFrameHeatGain(surfNum) = state.dataSurface->SurfWinFrameHeatGain(repSurfNum) * frameAreaRatio; - state.dataSurface->SurfWinFrameHeatLoss(surfNum) = state.dataSurface->SurfWinFrameHeatLoss(repSurfNum) * frameAreaRatio; - state.dataSurface->SurfWinFrameTempIn(surfNum) = state.dataSurface->SurfWinFrameTempIn(repSurfNum); - state.dataSurface->SurfWinFrameTempSurfOut(surfNum) = state.dataSurface->SurfWinFrameTempSurfOut(repSurfNum); - frameHeatGain = state.dataSurface->SurfWinFrameHeatGain(surfNum) - state.dataSurface->SurfWinFrameHeatLoss(surfNum); - } + // Frame + Real64 frameHeatGain = 0.0; + if (state.dataSurface->SurfWinFrameArea(surfNum) > 0.0) { + auto frameAreaRatio = state.dataSurface->SurfWinFrameArea(surfNum) / state.dataSurface->SurfWinFrameArea(repSurfNum); + state.dataSurface->SurfWinFrameHeatGain(surfNum) = state.dataSurface->SurfWinFrameHeatGain(repSurfNum) * frameAreaRatio; + state.dataSurface->SurfWinFrameHeatLoss(surfNum) = state.dataSurface->SurfWinFrameHeatLoss(repSurfNum) * frameAreaRatio; + state.dataSurface->SurfWinFrameTempIn(surfNum) = state.dataSurface->SurfWinFrameTempIn(repSurfNum); + state.dataSurface->SurfWinFrameTempSurfOut(surfNum) = state.dataSurface->SurfWinFrameTempSurfOut(repSurfNum); + frameHeatGain = state.dataSurface->SurfWinFrameHeatGain(surfNum) - state.dataSurface->SurfWinFrameHeatLoss(surfNum); + } - // Divider - Real64 dividerHeatGain = 0.0; - if (state.dataSurface->SurfWinDividerArea(surfNum) > 0.0) { - auto dividerAreaRatio = state.dataSurface->SurfWinDividerArea(surfNum) / state.dataSurface->SurfWinDividerArea(repSurfNum); - state.dataSurface->SurfWinDividerHeatGain(surfNum) = state.dataSurface->SurfWinDividerHeatGain(repSurfNum) * dividerAreaRatio; - state.dataSurface->SurfWinDividerHeatLoss(surfNum) = state.dataSurface->SurfWinDividerHeatLoss(repSurfNum) * dividerAreaRatio; - state.dataSurface->SurfWinDividerTempIn(surfNum) = state.dataSurface->SurfWinDividerTempIn(repSurfNum); - state.dataSurface->SurfWinDividerTempSurfOut(surfNum) = state.dataSurface->SurfWinDividerTempSurfOut(repSurfNum); - dividerHeatGain = state.dataSurface->SurfWinDividerHeatGain(surfNum) - state.dataSurface->SurfWinDividerHeatLoss(surfNum); - } + // Divider + Real64 dividerHeatGain = 0.0; + if (state.dataSurface->SurfWinDividerArea(surfNum) > 0.0) { + auto dividerAreaRatio = state.dataSurface->SurfWinDividerArea(surfNum) / state.dataSurface->SurfWinDividerArea(repSurfNum); + state.dataSurface->SurfWinDividerHeatGain(surfNum) = state.dataSurface->SurfWinDividerHeatGain(repSurfNum) * dividerAreaRatio; + state.dataSurface->SurfWinDividerHeatLoss(surfNum) = state.dataSurface->SurfWinDividerHeatLoss(repSurfNum) * dividerAreaRatio; + state.dataSurface->SurfWinDividerTempIn(surfNum) = state.dataSurface->SurfWinDividerTempIn(repSurfNum); + state.dataSurface->SurfWinDividerTempSurfOut(surfNum) = state.dataSurface->SurfWinDividerTempSurfOut(repSurfNum); + dividerHeatGain = state.dataSurface->SurfWinDividerHeatGain(surfNum) - state.dataSurface->SurfWinDividerHeatLoss(surfNum); + } - state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = frameHeatGain + dividerHeatGain; + state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = frameHeatGain + dividerHeatGain; - // Whole window - state.dataSurface->SurfWinHeatGain(surfNum) = - (state.dataSurface->SurfWinHeatGain(repSurfNum) - state.dataSurface->SurfWinGainFrameDividerToZoneRep(repSurfNum) * areaRatio) + - state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum); + // Whole window + state.dataSurface->SurfWinHeatGain(surfNum) = (state.dataSurface->SurfWinHeatGain(repSurfNum) - + state.dataSurface->SurfWinGainFrameDividerToZoneRep(repSurfNum) * areaRatio) + + state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum); + } } } } @@ -5091,70 +5137,74 @@ void UpdateThermalHistories(EnergyPlusData &state) auto &Surface(state.dataSurface->Surface); for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurfOpaq = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceFirst; - int const lastSurfOpaq = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceLast; - for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) { - // Loop through all (heat transfer) surfaces... [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum ) - auto const &surface(Surface(SurfNum)); + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst; + int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast; + for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) { + // Loop through all (heat transfer) surfaces... [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum ) + auto const &surface(Surface(SurfNum)); - if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) && - (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) - continue; + if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) && + (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) + continue; - int const ConstrNum(surface.Construction); - auto const &construct(state.dataConstruction->Construct(ConstrNum)); + int const ConstrNum(surface.Construction); + auto const &construct(state.dataConstruction->Construct(ConstrNum)); - if (construct.NumCTFTerms == 0) continue; // Skip surfaces with no history terms - - // Sign convention for the various terms in the following two equations - // is based on the form of the Conduction Transfer Function equation - // given by: - // Qin,now = (Sum of)(Y Tout) - (Sum of)(Z Tin) + (Sum of)(F Qin,old) + (Sum of)(V Qsrc) - // Qout,now = (Sum of)(X Tout) - (Sum of)(Y Tin) + (Sum of)(F Qout,old) + (Sum of)(W Qsrc) - // In both equations, flux is positive from outside to inside. The V and W terms are for radiant systems only. - - // Set current inside flux: - Real64 const SurfOutsideTempCurr = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum); - Real64 SurfInsideFluxHistCurr = SurfOutsideTempCurr * construct.CTFCross(0) - - state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFInside(0) + - state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum); // Heat source/sink term for radiant systems - // Only HT opaq surfaces are evaluated, previous if (surface.Class == SurfaceClass::Floor || surface.Class == SurfaceClass::Wall || - // surface.Class == SurfaceClass::IntMass || surface.Class == SurfaceClass::Roof || surface.Class == SurfaceClass::Door) checks are - // reduncant. - if (construct.SourceSinkPresent) { - SurfInsideFluxHistCurr += state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFSourceIn(0); - } - state.dataHeatBalSurf->SurfOpaqInsFaceCond(SurfNum) = surface.Area * SurfInsideFluxHistCurr; - state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum) = SurfInsideFluxHistCurr; // for reporting - state.dataHeatBalSurf->SurfInsideFluxHist(1)(SurfNum) = SurfInsideFluxHistCurr; + if (construct.NumCTFTerms == 0) continue; // Skip surfaces with no history terms - // Update the temperature at the source/sink location (if one is present) - if (construct.SourceSinkPresent) { - state.dataHeatBalSurf->SurfTempSource(SurfNum) = state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 1) = - SurfOutsideTempCurr * construct.CTFTSourceOut(0) + state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFTSourceIn(0) + - state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFTSourceQ(0) + state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum); - state.dataHeatBalSurf->SurfTempUserLoc(SurfNum) = state.dataHeatBalSurf->SurfTuserHist(SurfNum, 1) = - SurfOutsideTempCurr * construct.CTFTUserOut(0) + state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFTUserIn(0) + - state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFTUserSource(0) + - state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum); - } + // Sign convention for the various terms in the following two equations + // is based on the form of the Conduction Transfer Function equation + // given by: + // Qin,now = (Sum of)(Y Tout) - (Sum of)(Z Tin) + (Sum of)(F Qin,old) + (Sum of)(V Qsrc) + // Qout,now = (Sum of)(X Tout) - (Sum of)(Y Tin) + (Sum of)(F Qout,old) + (Sum of)(W Qsrc) + // In both equations, flux is positive from outside to inside. The V and W terms are for radiant systems only. + + // Set current inside flux: + Real64 const SurfOutsideTempCurr = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum); + Real64 SurfInsideFluxHistCurr = SurfOutsideTempCurr * construct.CTFCross(0) - + state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFInside(0) + + state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum); // Heat source/sink term for radiant systems + // Only HT opaq surfaces are evaluated, previous if (surface.Class == SurfaceClass::Floor || surface.Class == SurfaceClass::Wall || + // surface.Class == SurfaceClass::IntMass || surface.Class == SurfaceClass::Roof || surface.Class == SurfaceClass::Door) checks are + // reduncant. + if (construct.SourceSinkPresent) { + SurfInsideFluxHistCurr += state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFSourceIn(0); + } + state.dataHeatBalSurf->SurfOpaqInsFaceCond(SurfNum) = surface.Area * SurfInsideFluxHistCurr; + state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(SurfNum) = SurfInsideFluxHistCurr; // for reporting + state.dataHeatBalSurf->SurfInsideFluxHist(1)(SurfNum) = SurfInsideFluxHistCurr; - if (surface.ExtBoundCond > 0) continue; // Don't need to evaluate outside for partitions + // Update the temperature at the source/sink location (if one is present) + if (construct.SourceSinkPresent) { + state.dataHeatBalSurf->SurfTempSource(SurfNum) = state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 1) = + SurfOutsideTempCurr * construct.CTFTSourceOut(0) + state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFTSourceIn(0) + + state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFTSourceQ(0) + + state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum); + state.dataHeatBalSurf->SurfTempUserLoc(SurfNum) = state.dataHeatBalSurf->SurfTuserHist(SurfNum, 1) = + SurfOutsideTempCurr * construct.CTFTUserOut(0) + state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFTUserIn(0) + + state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFTUserSource(0) + + state.dataHeatBalFanSys->CTFTuserConstPart(SurfNum); + } - // Set current outside flux: - if (construct.SourceSinkPresent) { - state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum) = - SurfOutsideTempCurr * construct.CTFOutside(0) - state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFCross(0) + - state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFSourceOut(0) + - state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum); // Heat source/sink term for radiant systems - } else { - state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum) = SurfOutsideTempCurr * construct.CTFOutside(0) - - state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFCross(0) + - state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum); + if (surface.ExtBoundCond > 0) continue; // Don't need to evaluate outside for partitions + + // Set current outside flux: + if (construct.SourceSinkPresent) { + state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum) = + SurfOutsideTempCurr * construct.CTFOutside(0) - state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFCross(0) + + state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) * construct.CTFSourceOut(0) + + state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum); // Heat source/sink term for radiant systems + } else { + state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum) = SurfOutsideTempCurr * construct.CTFOutside(0) - + state.dataHeatBalSurf->SurfTempIn(SurfNum) * construct.CTFCross(0) + + state.dataHeatBalSurf->SurfCTFConstOutPart(SurfNum); + } + // switch sign for balance at outside face + state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum) = -state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum); + state.dataHeatBalSurf->SurfOpaqOutFaceCond(SurfNum) = surface.Area * state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum); } - // switch sign for balance at outside face - state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum) = -state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum); - state.dataHeatBalSurf->SurfOpaqOutFaceCond(SurfNum) = surface.Area * state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(SurfNum); } } // ...end of loop over all (heat transfer) surfaces... @@ -5185,35 +5235,41 @@ void UpdateThermalHistories(EnergyPlusData &state) } for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurfOpaq = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceFirst; - int const lastSurfOpaq = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceLast; - for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) { - // Loop through all (heat transfer) surfaces... [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum ) - if ((Surface(SurfNum).HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) && - (Surface(SurfNum).HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) - continue; - if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays - state.dataHeatBalSurfMgr->TempExt1(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum); - state.dataHeatBalSurfMgr->TempInt1(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum); - state.dataHeatBalSurfMgr->QExt1(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum); - state.dataHeatBalSurfMgr->QInt1(SurfNum) = state.dataHeatBalSurf->SurfInsideFluxHist(1)(SurfNum); - } - } - - } // ...end of loop over all (heat transfer) surfaces... - if (state.dataHeatBal->AnyInternalHeatSourceInInput) { - for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurfOpaq = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceFirst; - int const lastSurfOpaq = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceLast; + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst; + int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast; for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) { // Loop through all (heat transfer) surfaces... [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum ) if ((Surface(SurfNum).HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) && (Surface(SurfNum).HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) continue; if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays - state.dataHeatBalSurfMgr->Tsrc1(SurfNum) = state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 1); - state.dataHeatBalSurfMgr->Tuser1(SurfNum) = state.dataHeatBalSurf->SurfTuserHist(SurfNum, 1); - state.dataHeatBalSurfMgr->Qsrc1(SurfNum) = state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1); + state.dataHeatBalSurfMgr->TempExt1(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum); + state.dataHeatBalSurfMgr->TempInt1(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum); + state.dataHeatBalSurfMgr->QExt1(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHist(1)(SurfNum); + state.dataHeatBalSurfMgr->QInt1(SurfNum) = state.dataHeatBalSurf->SurfInsideFluxHist(1)(SurfNum); + } + } + } + + } // ...end of loop over all (heat transfer) surfaces... + if (state.dataHeatBal->AnyInternalHeatSourceInInput) { + for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst; + int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast; + for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) { + // Loop through all (heat transfer) surfaces... [ l11 ] = ( 1, 1, SurfNum ), [ l21 ] = ( 2, 1, SurfNum ) + if ((Surface(SurfNum).HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) && + (Surface(SurfNum).HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) + continue; + if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays + state.dataHeatBalSurfMgr->Tsrc1(SurfNum) = state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 1); + state.dataHeatBalSurfMgr->Tuser1(SurfNum) = state.dataHeatBalSurf->SurfTuserHist(SurfNum, 1); + state.dataHeatBalSurfMgr->Qsrc1(SurfNum) = state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1); + } } } } // ...end of loop over all (heat transfer) surfaces... @@ -5222,165 +5278,173 @@ void UpdateThermalHistories(EnergyPlusData &state) // SHIFT TEMPERATURE AND FLUX HISTORIES: // SHIFT AIR TEMP AND FLUX SHIFT VALUES WHEN AT BOTTOM OF ARRAY SPACE. for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurfOpaq = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceFirst; - int const lastSurfOpaq = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceLast; - for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) { - auto const &surface(Surface(SurfNum)); + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst; + int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast; + for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) { + auto const &surface(Surface(SurfNum)); + + if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) && + (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) + continue; - if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) && - (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) - continue; + int const ConstrNum(surface.Construction); + auto const &construct(state.dataConstruction->Construct(ConstrNum)); - int const ConstrNum(surface.Construction); - auto const &construct(state.dataConstruction->Construct(ConstrNum)); + ++state.dataHeatBalSurf->SurfCurrNumHist(SurfNum); + state.dataHeatBalSurfMgr->SumTime(SurfNum) = double(state.dataHeatBalSurf->SurfCurrNumHist(SurfNum)) * state.dataGlobal->TimeStepZone; - ++state.dataHeatBalSurf->SurfCurrNumHist(SurfNum); - state.dataHeatBalSurfMgr->SumTime(SurfNum) = double(state.dataHeatBalSurf->SurfCurrNumHist(SurfNum)) * state.dataGlobal->TimeStepZone; - - if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == construct.NumHistories) { - state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) = 0; - - if (construct.NumCTFTerms > 1) { - int const numCTFTerms(construct.NumCTFTerms); - for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum) { // Tuned Linear indexing - state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum)(SurfNum) = - state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum); - state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum)(SurfNum) = - state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum); - state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum)(SurfNum) = - state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum); - state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum)(SurfNum) = - state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum); - state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum)(SurfNum) = - state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum); - state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum)(SurfNum) = - state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum); - state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum)(SurfNum) = - state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum); - state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum)(SurfNum) = - state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum); + if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == construct.NumHistories) { + state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) = 0; + + if (construct.NumCTFTerms > 1) { + int const numCTFTerms(construct.NumCTFTerms); + for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum) { // Tuned Linear indexing + state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum)(SurfNum) = + state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum); + state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum)(SurfNum) = + state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum); + state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum)(SurfNum) = + state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum); + state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum)(SurfNum) = + state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum); + state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum)(SurfNum) = + state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum); + state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum)(SurfNum) = + state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum); + state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum)(SurfNum) = + state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum); + state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum)(SurfNum) = + state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum); + } } - } - state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->TempExt1(SurfNum); - state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->TempInt1(SurfNum); - state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->QExt1(SurfNum); - state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->QInt1(SurfNum); + state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->TempExt1(SurfNum); + state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->TempInt1(SurfNum); + state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->QExt1(SurfNum); + state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) = state.dataHeatBalSurfMgr->QInt1(SurfNum); - state.dataHeatBalSurf->SurfOutsideTempHist(2)(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum); - state.dataHeatBalSurf->SurfInsideTempHist(2)(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum); - state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum); - state.dataHeatBalSurf->SurfInsideFluxHist(2)(SurfNum) = state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum); - } else { - Real64 const sum_steps(state.dataHeatBalSurfMgr->SumTime(SurfNum) / construct.CTFTimeStep); - if (construct.NumCTFTerms > 1) { - int const numCTFTerms(construct.NumCTFTerms); - for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum) { // Tuned Linear indexing - // TH(SideNum, TermNum, SurfNum) = (THM(SideNum, TermNum, SurfNum) - - // (THM(SideNum, TermNum, SurfNum) - THM(SideNum, TermNum - 1, SurfNum)) * sum_steps; - Real64 const THM_Out_1(state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum)(SurfNum)); - Real64 const THM_In_1(state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum)(SurfNum)); - Real64 const THM_Out_2(state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum)); - Real64 const THM_In_2(state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum)); - state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum)(SurfNum) = THM_Out_1 - (THM_Out_1 - THM_Out_2) * sum_steps; - state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum)(SurfNum) = THM_In_1 - (THM_In_1 - THM_In_2) * sum_steps; - - Real64 const QHM_Out_1(state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum)(SurfNum)); - Real64 const QHM_In_1(state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum)(SurfNum)); - Real64 const QHM_Out_2(state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum)); - Real64 const QHM_In_2(state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum)); - state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum)(SurfNum) = QHM_Out_1 - (QHM_Out_1 - QHM_Out_2) * sum_steps; - state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum)(SurfNum) = QHM_In_1 - (QHM_In_1 - QHM_In_2) * sum_steps; + state.dataHeatBalSurf->SurfOutsideTempHist(2)(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum); + state.dataHeatBalSurf->SurfInsideTempHist(2)(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum); + state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum) = state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum); + state.dataHeatBalSurf->SurfInsideFluxHist(2)(SurfNum) = state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum); + } else { + Real64 const sum_steps(state.dataHeatBalSurfMgr->SumTime(SurfNum) / construct.CTFTimeStep); + if (construct.NumCTFTerms > 1) { + int const numCTFTerms(construct.NumCTFTerms); + for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum) { // Tuned Linear indexing + // TH(SideNum, TermNum, SurfNum) = (THM(SideNum, TermNum, SurfNum) - + // (THM(SideNum, TermNum, SurfNum) - THM(SideNum, TermNum - 1, SurfNum)) * sum_steps; + Real64 const THM_Out_1(state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum)(SurfNum)); + Real64 const THM_In_1(state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum)(SurfNum)); + Real64 const THM_Out_2(state.dataHeatBalSurf->SurfOutsideTempHistMaster(HistTermNum - 1)(SurfNum)); + Real64 const THM_In_2(state.dataHeatBalSurf->SurfInsideTempHistMaster(HistTermNum - 1)(SurfNum)); + state.dataHeatBalSurf->SurfOutsideTempHist(HistTermNum)(SurfNum) = THM_Out_1 - (THM_Out_1 - THM_Out_2) * sum_steps; + state.dataHeatBalSurf->SurfInsideTempHist(HistTermNum)(SurfNum) = THM_In_1 - (THM_In_1 - THM_In_2) * sum_steps; + + Real64 const QHM_Out_1(state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum)(SurfNum)); + Real64 const QHM_In_1(state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum)(SurfNum)); + Real64 const QHM_Out_2(state.dataHeatBalSurf->SurfOutsideFluxHistMaster(HistTermNum - 1)(SurfNum)); + Real64 const QHM_In_2(state.dataHeatBalSurf->SurfInsideFluxHistMaster(HistTermNum - 1)(SurfNum)); + state.dataHeatBalSurf->SurfOutsideFluxHist(HistTermNum)(SurfNum) = QHM_Out_1 - (QHM_Out_1 - QHM_Out_2) * sum_steps; + state.dataHeatBalSurf->SurfInsideFluxHist(HistTermNum)(SurfNum) = QHM_In_1 - (QHM_In_1 - QHM_In_2) * sum_steps; + } } + // TH( 1, 2, SurfNum ) = THM( 1, 2, SurfNum ) - ( THM( 1, 2, SurfNum ) - TempExt1( SurfNum ) ) * sum_steps; + state.dataHeatBalSurf->SurfOutsideTempHist(2)(SurfNum) = + state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) - + (state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->TempExt1(SurfNum)) * sum_steps; + state.dataHeatBalSurf->SurfInsideTempHist(2)(SurfNum) = + state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) - + (state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->TempInt1(SurfNum)) * sum_steps; + state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum) = + state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) - + (state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->QExt1(SurfNum)) * sum_steps; + state.dataHeatBalSurf->SurfInsideFluxHist(2)(SurfNum) = + state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) - + (state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->QInt1(SurfNum)) * sum_steps; } - // TH( 1, 2, SurfNum ) = THM( 1, 2, SurfNum ) - ( THM( 1, 2, SurfNum ) - TempExt1( SurfNum ) ) * sum_steps; - state.dataHeatBalSurf->SurfOutsideTempHist(2)(SurfNum) = - state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) - - (state.dataHeatBalSurf->SurfOutsideTempHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->TempExt1(SurfNum)) * sum_steps; - state.dataHeatBalSurf->SurfInsideTempHist(2)(SurfNum) = - state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) - - (state.dataHeatBalSurf->SurfInsideTempHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->TempInt1(SurfNum)) * sum_steps; - state.dataHeatBalSurf->SurfOutsideFluxHist(2)(SurfNum) = - state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) - - (state.dataHeatBalSurf->SurfOutsideFluxHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->QExt1(SurfNum)) * sum_steps; - state.dataHeatBalSurf->SurfInsideFluxHist(2)(SurfNum) = - state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) - - (state.dataHeatBalSurf->SurfInsideFluxHistMaster(2)(SurfNum) - state.dataHeatBalSurfMgr->QInt1(SurfNum)) * sum_steps; } } } // ...end of loop over all (heat transfer) surfaces if (state.dataHeatBal->AnyInternalHeatSourceInInput) { for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurfOpaq = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceFirst; - int const lastSurfOpaq = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceLast; - for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) { - auto const &surface(Surface(SurfNum)); - int const ConstrNum(surface.Construction); - auto const &construct(state.dataConstruction->Construct(ConstrNum)); - if (!construct.SourceSinkPresent) continue; - if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) && - (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) - continue; - - if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays - if (construct.NumCTFTerms > 1) { - int const numCTFTerms(construct.NumCTFTerms); - auto m(state.dataHeatBalSurf->SurfTsrcHistM.index(SurfNum, numCTFTerms)); - auto m1(m + 1); - for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum, --m, --m1) { // Tuned Linear indexing - // SurfTsrcHist( SurfNum, HistTerm ) = SurfTsrcHistM( SurfNum, HHistTerm ) = SurfTsrcHistM( SurfNum, HistTermNum - 1 ); - // SurfQsrcHist( SurfNum, HistTerm ) = SurfQsrcHistM( SurfNum, HHistTerm ) = SurfQsrcHistM( SurfNum, HistTermNum - 1 ); - state.dataHeatBalSurf->SurfTsrcHist[m1] = state.dataHeatBalSurf->SurfTsrcHistM[m1] = - state.dataHeatBalSurf->SurfTsrcHistM[m]; - state.dataHeatBalSurf->SurfQsrcHist[m1] = state.dataHeatBalSurf->SurfQsrcHistM[m1] = - state.dataHeatBalSurf->SurfQsrcHistM[m]; - state.dataHeatBalSurf->SurfTuserHist[m1] = state.dataHeatBalSurf->SurfTuserHistM[m1] = - state.dataHeatBalSurf->SurfTuserHistM[m]; + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurfOpaq = thisSpace.OpaqOrIntMassSurfaceFirst; + int const lastSurfOpaq = thisSpace.OpaqOrIntMassSurfaceLast; + for (int SurfNum = firstSurfOpaq; SurfNum <= lastSurfOpaq; ++SurfNum) { + auto const &surface(Surface(SurfNum)); + int const ConstrNum(surface.Construction); + auto const &construct(state.dataConstruction->Construct(ConstrNum)); + if (!construct.SourceSinkPresent) continue; + if ((surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::CTF) && + (surface.HeatTransferAlgorithm != DataSurfaces::HeatTransferModel::EMPD)) + continue; + + if (state.dataHeatBalSurf->SurfCurrNumHist(SurfNum) == 0) { // First time step in a block for a surface, update arrays + if (construct.NumCTFTerms > 1) { + int const numCTFTerms(construct.NumCTFTerms); + auto m(state.dataHeatBalSurf->SurfTsrcHistM.index(SurfNum, numCTFTerms)); + auto m1(m + 1); + for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum, --m, --m1) { // Tuned Linear indexing + // SurfTsrcHist( SurfNum, HistTerm ) = SurfTsrcHistM( SurfNum, HHistTerm ) = SurfTsrcHistM( SurfNum, HistTermNum - 1 + // ); SurfQsrcHist( SurfNum, HistTerm ) = SurfQsrcHistM( SurfNum, HHistTerm ) = SurfQsrcHistM( SurfNum, HistTermNum - + // 1 ); + state.dataHeatBalSurf->SurfTsrcHist[m1] = state.dataHeatBalSurf->SurfTsrcHistM[m1] = + state.dataHeatBalSurf->SurfTsrcHistM[m]; + state.dataHeatBalSurf->SurfQsrcHist[m1] = state.dataHeatBalSurf->SurfQsrcHistM[m1] = + state.dataHeatBalSurf->SurfQsrcHistM[m]; + state.dataHeatBalSurf->SurfTuserHist[m1] = state.dataHeatBalSurf->SurfTuserHistM[m1] = + state.dataHeatBalSurf->SurfTuserHistM[m]; + } } - } - state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Tsrc1(SurfNum); - state.dataHeatBalSurf->SurfTuserHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Tuser1(SurfNum); - state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Qsrc1(SurfNum); - state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 2) = state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, 2); - state.dataHeatBalSurf->SurfTuserHist(SurfNum, 2) = state.dataHeatBalSurf->SurfTuserHistM(SurfNum, 2); - state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 2) = state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, 2); - } else { - Real64 const sum_steps(state.dataHeatBalSurfMgr->SumTime(SurfNum) / construct.CTFTimeStep); - - if (construct.NumCTFTerms > 1) { - int const numCTFTerms(construct.NumCTFTerms); - auto m(state.dataHeatBalSurf->SurfTsrcHistM.index(SurfNum, numCTFTerms)); - auto m1(m + 1); - for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum, --m, --m1) { // Tuned Linear indexing [ l ] == () - // Real64 const SurfTsrcHistM_elem( SurfTsrcHistM( SurfNum, HistTermNum ) ); - // SurfTsrcHist( SurfNum, HistTermNum ) = SurfTsrcHistM_elem - ( SurfTsrcHistM_elem - SurfTsrcHistM( SurfNum, HistTermNum - // - 1 ) ) * sum_steps; Real64 const QsrcHistM_elem( SurfQsrcHistM( SurfNum, HistTermNum ) ); SurfQsrcHist( SurfNum, - // HistTermNum ) = QsrcHistM_elem - ( QsrcHistM_elem - SurfQsrcHistM( SurfNum, HistTermNum - 1 ) ) * sum_steps; - Real64 const TsrcHistM_m1(state.dataHeatBalSurf->SurfTsrcHistM[m1]); - state.dataHeatBalSurf->SurfTsrcHist[m1] = - TsrcHistM_m1 - (TsrcHistM_m1 - state.dataHeatBalSurf->SurfTsrcHistM[m]) * sum_steps; - Real64 const QsrcHistM_m1(state.dataHeatBalSurf->SurfQsrcHistM[m1]); - state.dataHeatBalSurf->SurfQsrcHist[m1] = - QsrcHistM_m1 - (QsrcHistM_m1 - state.dataHeatBalSurf->SurfQsrcHistM[m]) * sum_steps; - Real64 const TuserHistM_m1(state.dataHeatBalSurf->SurfTuserHistM[m1]); - state.dataHeatBalSurf->SurfTuserHist[m1] = - TuserHistM_m1 - (TuserHistM_m1 - state.dataHeatBalSurf->SurfTuserHistM[m]) * sum_steps; + state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Tsrc1(SurfNum); + state.dataHeatBalSurf->SurfTuserHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Tuser1(SurfNum); + state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, 2) = state.dataHeatBalSurfMgr->Qsrc1(SurfNum); + state.dataHeatBalSurf->SurfTsrcHist(SurfNum, 2) = state.dataHeatBalSurf->SurfTsrcHistM(SurfNum, 2); + state.dataHeatBalSurf->SurfTuserHist(SurfNum, 2) = state.dataHeatBalSurf->SurfTuserHistM(SurfNum, 2); + state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 2) = state.dataHeatBalSurf->SurfQsrcHistM(SurfNum, 2); + } else { + Real64 const sum_steps(state.dataHeatBalSurfMgr->SumTime(SurfNum) / construct.CTFTimeStep); + + if (construct.NumCTFTerms > 1) { + int const numCTFTerms(construct.NumCTFTerms); + auto m(state.dataHeatBalSurf->SurfTsrcHistM.index(SurfNum, numCTFTerms)); + auto m1(m + 1); + for (int HistTermNum = numCTFTerms + 1; HistTermNum >= 3; --HistTermNum, --m, --m1) { // Tuned Linear indexing [ l ] == () + // Real64 const SurfTsrcHistM_elem( SurfTsrcHistM( SurfNum, HistTermNum ) ); + // SurfTsrcHist( SurfNum, HistTermNum ) = SurfTsrcHistM_elem - ( SurfTsrcHistM_elem - SurfTsrcHistM( SurfNum, + // HistTermNum + // - 1 ) ) * sum_steps; Real64 const QsrcHistM_elem( SurfQsrcHistM( SurfNum, HistTermNum ) ); SurfQsrcHist( SurfNum, + // HistTermNum ) = QsrcHistM_elem - ( QsrcHistM_elem - SurfQsrcHistM( SurfNum, HistTermNum - 1 ) ) * sum_steps; + Real64 const TsrcHistM_m1(state.dataHeatBalSurf->SurfTsrcHistM[m1]); + state.dataHeatBalSurf->SurfTsrcHist[m1] = + TsrcHistM_m1 - (TsrcHistM_m1 - state.dataHeatBalSurf->SurfTsrcHistM[m]) * sum_steps; + Real64 const QsrcHistM_m1(state.dataHeatBalSurf->SurfQsrcHistM[m1]); + state.dataHeatBalSurf->SurfQsrcHist[m1] = + QsrcHistM_m1 - (QsrcHistM_m1 - state.dataHeatBalSurf->SurfQsrcHistM[m]) * sum_steps; + Real64 const TuserHistM_m1(state.dataHeatBalSurf->SurfTuserHistM[m1]); + state.dataHeatBalSurf->SurfTuserHist[m1] = + TuserHistM_m1 - (TuserHistM_m1 - state.dataHeatBalSurf->SurfTuserHistM[m]) * sum_steps; + } } + // Tuned Linear indexing + // SurfTsrcHist( SurfNum, 2 ) = SurfTsrcHistM( SurfNum, 2 ) - ( SurfTsrcHistM( SurfNum, 2 ) - Tsrc1( SurfNum ) ) * sum_steps; + // SurfQsrcHist( SurfNum, 2 ) = SurfQsrcHistM( SurfNum, 2 ) - ( SurfQsrcHistM( SurfNum, 2 ) - Qsrc1( SurfNum ) ) * sum_steps; + auto const l2(state.dataHeatBalSurf->SurfTsrcHist.index(SurfNum, 2)); + state.dataHeatBalSurf->SurfTsrcHist[l2] = + state.dataHeatBalSurf->SurfTsrcHistM[l2] - + (state.dataHeatBalSurf->SurfTsrcHistM[l2] - state.dataHeatBalSurfMgr->Tsrc1(SurfNum)) * sum_steps; + state.dataHeatBalSurf->SurfQsrcHist[l2] = + state.dataHeatBalSurf->SurfQsrcHistM[l2] - + (state.dataHeatBalSurf->SurfQsrcHistM[l2] - state.dataHeatBalSurfMgr->Qsrc1(SurfNum)) * sum_steps; + state.dataHeatBalSurf->SurfTuserHist[l2] = + state.dataHeatBalSurf->SurfTuserHistM[l2] - + (state.dataHeatBalSurf->SurfTuserHistM[l2] - state.dataHeatBalSurfMgr->Tuser1(SurfNum)) * sum_steps; } - // Tuned Linear indexing - // SurfTsrcHist( SurfNum, 2 ) = SurfTsrcHistM( SurfNum, 2 ) - ( SurfTsrcHistM( SurfNum, 2 ) - Tsrc1( SurfNum ) ) * sum_steps; - // SurfQsrcHist( SurfNum, 2 ) = SurfQsrcHistM( SurfNum, 2 ) - ( SurfQsrcHistM( SurfNum, 2 ) - Qsrc1( SurfNum ) ) * sum_steps; - auto const l2(state.dataHeatBalSurf->SurfTsrcHist.index(SurfNum, 2)); - state.dataHeatBalSurf->SurfTsrcHist[l2] = - state.dataHeatBalSurf->SurfTsrcHistM[l2] - - (state.dataHeatBalSurf->SurfTsrcHistM[l2] - state.dataHeatBalSurfMgr->Tsrc1(SurfNum)) * sum_steps; - state.dataHeatBalSurf->SurfQsrcHist[l2] = - state.dataHeatBalSurf->SurfQsrcHistM[l2] - - (state.dataHeatBalSurf->SurfQsrcHistM[l2] - state.dataHeatBalSurfMgr->Qsrc1(SurfNum)) * sum_steps; - state.dataHeatBalSurf->SurfTuserHist[l2] = - state.dataHeatBalSurf->SurfTuserHistM[l2] - - (state.dataHeatBalSurf->SurfTuserHistM[l2] - state.dataHeatBalSurfMgr->Tuser1(SurfNum)) * sum_steps; } } } // ...end of loop over all (heat transfer) surfaces... @@ -5402,8 +5466,6 @@ void CalculateZoneMRT(EnergyPlusData &state, // calculation purposes. Real64 SumAET; // Intermediate calculational variable (area*emissivity*T) sum - int SurfNum; // Surface number - int ZoneNum; // Zone number auto &Surface(state.dataSurface->Surface); @@ -5412,31 +5474,35 @@ void CalculateZoneMRT(EnergyPlusData &state, state.dataHeatBalSurfMgr->ZoneAESum.allocate(state.dataGlobal->NumOfZones); state.dataHeatBalSurfMgr->SurfaceAE = 0.0; state.dataHeatBalSurfMgr->ZoneAESum = 0.0; - for (SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) { + for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) { if (Surface(SurfNum).HeatTransSurf) { state.dataHeatBalSurfMgr->SurfaceAE(SurfNum) = Surface(SurfNum).Area * state.dataConstruction->Construct(Surface(SurfNum).Construction).InsideAbsorpThermal; - ZoneNum = Surface(SurfNum).Zone; + int ZoneNum = Surface(SurfNum).Zone; if (ZoneNum > 0) state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum) += state.dataHeatBalSurfMgr->SurfaceAE(SurfNum); } } } - for (ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { + for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { if (present(ZoneToResimulate) && (ZoneNum != ZoneToResimulate)) continue; SumAET = 0.0; - for (SurfNum = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst; SurfNum <= state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast; ++SurfNum) { - SumAET += state.dataHeatBalSurfMgr->SurfaceAE(SurfNum) * state.dataHeatBalSurf->SurfTempIn(SurfNum); - } - if (state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum) > 0.01) { - state.dataHeatBal->ZoneMRT(ZoneNum) = SumAET / state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum); - } else { - if (state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime) { - ShowWarningError( - state, "Zone areas*inside surface emissivities are summing to zero, for Zone=\"" + state.dataHeatBal->Zone(ZoneNum).Name + "\""); - ShowContinueError(state, "As a result, MRT will be set to MAT for that zone"); + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { + SumAET += state.dataHeatBalSurfMgr->SurfaceAE(SurfNum) * state.dataHeatBalSurf->SurfTempIn(SurfNum); + } + if (state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum) > 0.01) { + state.dataHeatBal->ZoneMRT(ZoneNum) = SumAET / state.dataHeatBalSurfMgr->ZoneAESum(ZoneNum); + } else { + if (state.dataHeatBalSurfMgr->CalculateZoneMRTfirstTime) { + ShowWarningError(state, + "Zone areas*inside surface emissivities are summing to zero, for Zone=\"" + + state.dataHeatBal->Zone(ZoneNum).Name + "\""); + ShowContinueError(state, "As a result, MRT will be set to MAT for that zone"); + } + state.dataHeatBal->ZoneMRT(ZoneNum) = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; } - state.dataHeatBal->ZoneMRT(ZoneNum) = state.dataHeatBalFanSys->MAT(ZoneNum); } } @@ -5504,8 +5570,8 @@ void CalcThermalResilience(EnergyPlusData &state) Real64 constexpr c8 = .00085282; Real64 constexpr c9 = -.00000199; for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { - Real64 const ZoneT = state.dataHeatBalFanSys->ZTAV(ZoneNum); - Real64 const ZoneW = state.dataHeatBalFanSys->ZoneAirHumRatAvg(ZoneNum); + Real64 const ZoneT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV; + Real64 const ZoneW = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZoneAirHumRatAvg; Real64 const ZoneRH = Psychrometrics::PsyRhFnTdbWPb(state, ZoneT, ZoneW, state.dataEnvrn->OutBaroPress) * 100.0; Real64 const ZoneTF = ZoneT * (9.0 / 5.0) + 32.0; Real64 HI; @@ -5527,8 +5593,8 @@ void CalcThermalResilience(EnergyPlusData &state) } if (state.dataHeatBalSurfMgr->reportVarHumidex || state.dataOutRptTab->displayThermalResilienceSummary) { for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { - Real64 const ZoneW = state.dataHeatBalFanSys->ZoneAirHumRatAvg(ZoneNum); - Real64 const ZoneT = state.dataHeatBalFanSys->ZTAV(ZoneNum); + Real64 const ZoneW = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZoneAirHumRatAvg; + Real64 const ZoneT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV; Real64 const TDewPointK = Psychrometrics::PsyTdpFnWPb(state, ZoneW, state.dataEnvrn->OutBaroPress) + DataGlobalConstants::KelvinConv; Real64 const e = 6.11 * std::exp(5417.7530 * ((1 / 273.16) - (1 / TDewPointK))); Real64 const h = 5.0 / 9.0 * (e - 10.0); @@ -5629,7 +5695,7 @@ void ReportThermalResilience(EnergyPlusData &state) } Real64 NumOcc = state.dataHeatBal->Resilience(ZoneNum).ZoneNumOcc; - Real64 Temperature = state.dataHeatBalFanSys->ZTAV(ZoneNum); + Real64 Temperature = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV; ColdTempThresh = state.dataHeatBal->People(iPeople).ColdStressTempThresh; bool &CrossedColdThresh = state.dataHeatBal->Resilience(ZoneNum).CrossedColdThresh; if (Temperature > ColdTempThresh) { // safe @@ -5874,7 +5940,7 @@ void ReportThermalResilience(EnergyPlusData &state) state.dataHeatBal->Resilience(ZoneNum).ZoneHumidexOccupiedHourBins[4] += (NumOcc > 0) * state.dataGlobal->TimeStepZone; } - Real64 Temperature = state.dataHeatBalFanSys->ZTAV(ZoneNum); + Real64 Temperature = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV; Real64 CoolingSetpoint = state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ZoneNum); Real64 HeatingSetpoint = state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ZoneNum); @@ -6094,7 +6160,7 @@ void ReportThermalResilience(EnergyPlusData &state) } } - Real64 Temperature = state.dataHeatBalFanSys->ZTAV(ZoneNum); + Real64 Temperature = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV; Real64 CoolingSetpoint = state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ZoneNum); Real64 HeatingSetpoint = state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ZoneNum); @@ -6354,42 +6420,47 @@ void ReportSurfaceHeatBalance(EnergyPlusData &state) // Opaque or window surfaces for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrWinSurfaceFirst; - int const lastSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrWinSurfaceLast; - for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - auto &surface(state.dataSurface->Surface(surfNum)); - // Inside Face Convection - sign convention is positive means energy going into inside face from the air. - state.dataHeatBalSurf->SurfQdotConvInRep(surfNum) = surface.Area * state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum); - state.dataHeatBalSurf->SurfQConvInReport(surfNum) = state.dataHeatBalSurf->SurfQdotConvInRep(surfNum) * state.dataGlobal->TimeStepZoneSec; + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst; + int const lastSurf = thisSpace.OpaqOrWinSurfaceLast; + for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { + auto &surface(state.dataSurface->Surface(surfNum)); + // Inside Face Convection - sign convention is positive means energy going into inside face from the air. + state.dataHeatBalSurf->SurfQdotConvInRep(surfNum) = surface.Area * state.dataHeatBalSurf->SurfQdotConvInPerArea(surfNum); + state.dataHeatBalSurf->SurfQConvInReport(surfNum) = + state.dataHeatBalSurf->SurfQdotConvInRep(surfNum) * state.dataGlobal->TimeStepZoneSec; - state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) * surface.Area; - state.dataHeatBalSurf->SurfQRadNetSurfInReport(surfNum) = - state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(surfNum) * state.dataGlobal->TimeStepZoneSec; + state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) * surface.Area; + state.dataHeatBalSurf->SurfQRadNetSurfInReport(surfNum) = + state.dataHeatBalSurf->SurfQdotRadNetSurfInRep(surfNum) * state.dataGlobal->TimeStepZoneSec; - state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(surfNum) = state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) * surface.Area; - state.dataHeatBalSurf->SurfQRadIntGainsInReport(surfNum) = - state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(surfNum) * state.dataGlobal->TimeStepZoneSec; + state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(surfNum) = state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) * surface.Area; + state.dataHeatBalSurf->SurfQRadIntGainsInReport(surfNum) = + state.dataHeatBalSurf->SurfQdotRadIntGainsInRep(surfNum) * state.dataGlobal->TimeStepZoneSec; - state.dataHeatBalSurf->SurfQdotRadHVACInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) * surface.Area; - state.dataHeatBalSurf->SurfQRadHVACInReport(surfNum) = - state.dataHeatBalSurf->SurfQdotRadHVACInRep(surfNum) * state.dataGlobal->TimeStepZoneSec; + state.dataHeatBalSurf->SurfQdotRadHVACInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) * surface.Area; + state.dataHeatBalSurf->SurfQRadHVACInReport(surfNum) = + state.dataHeatBalSurf->SurfQdotRadHVACInRep(surfNum) * state.dataGlobal->TimeStepZoneSec; - state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum) = state.dataHeatBalSurf->SurfQdotConvOutPerArea(surfNum) * surface.Area; + state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum) = state.dataHeatBalSurf->SurfQdotConvOutPerArea(surfNum) * surface.Area; - state.dataHeatBalSurf->SurfQConvOutReport(surfNum) = - state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum) * state.dataGlobal->TimeStepZoneSec; + state.dataHeatBalSurf->SurfQConvOutReport(surfNum) = + state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum) * state.dataGlobal->TimeStepZoneSec; - state.dataHeatBalSurf->SurfQdotRadOutRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(surfNum) * surface.Area; - state.dataHeatBalSurf->SurfQRadOutReport(surfNum) = state.dataHeatBalSurf->SurfQdotRadOutRep(surfNum) * state.dataGlobal->TimeStepZoneSec; + state.dataHeatBalSurf->SurfQdotRadOutRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadOutRepPerArea(surfNum) * surface.Area; + state.dataHeatBalSurf->SurfQRadOutReport(surfNum) = + state.dataHeatBalSurf->SurfQdotRadOutRep(surfNum) * state.dataGlobal->TimeStepZoneSec; - // Calculate surface heat emission to the air, positive values indicates heat transfer from surface to the outside - state.dataHeatBalSurf->SurfQAirExtReport(surfNum) = - surface.Area * state.dataHeatBalSurf->SurfHAirExt(surfNum) * - (state.dataHeatBalSurf->SurfTempOut(surfNum) - state.dataSurface->SurfOutDryBulbTemp(surfNum)); + // Calculate surface heat emission to the air, positive values indicates heat transfer from surface to the outside + state.dataHeatBalSurf->SurfQAirExtReport(surfNum) = + surface.Area * state.dataHeatBalSurf->SurfHAirExt(surfNum) * + (state.dataHeatBalSurf->SurfTempOut(surfNum) - state.dataSurface->SurfOutDryBulbTemp(surfNum)); - // Subtract since SurfQdotConvOutRep's convention is opposite (positive values indicate heat transfer from the outside to the surface) - state.dataHeatBalSurf->SurfQHeatEmiReport(surfNum) = - state.dataHeatBalSurf->SurfQAirExtReport(surfNum) - state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum); + // Subtract since SurfQdotConvOutRep's convention is opposite (positive values indicate heat transfer from the outside to the surface) + state.dataHeatBalSurf->SurfQHeatEmiReport(surfNum) = + state.dataHeatBalSurf->SurfQAirExtReport(surfNum) - state.dataHeatBalSurf->SurfQdotConvOutRep(surfNum); + } } } @@ -6405,57 +6476,60 @@ void ReportSurfaceHeatBalance(EnergyPlusData &state) // Window surfaces for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurf = state.dataHeatBal->Zone(zoneNum).WindowSurfaceFirst; - int const lastSurf = state.dataHeatBal->Zone(zoneNum).WindowSurfaceLast; - for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - auto &surface(state.dataSurface->Surface(surfNum)); - state.dataHeatBal->SurfWinInitialDifSolInTransReport(surfNum) = - state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(surfNum) * surface.Area; - - // Absorbed short wave radiation - int TotGlassLayers; - int const constrNum = state.dataSurface->SurfActiveConstruction(surfNum); - int const constrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(surfNum); - WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(surfNum); - if (state.dataSurface->SurfWinWindowModelType(surfNum) == WindowModel::EQL) { - TotGlassLayers = state.dataWindowEquivLayer->CFS(state.dataConstruction->Construct(constrNum).EQLConsPtr).NL; - } else if (state.dataSurface->SurfWinWindowModelType(surfNum) == WindowModel::BSDF) { - TotGlassLayers = state.dataConstruction->Construct(constrNum).TotSolidLayers; - } else if (NOT_SHADED(ShadeFlag) || ShadeFlag == WinShadingType::SwitchableGlazing) { - TotGlassLayers = state.dataConstruction->Construct(constrNum).TotGlassLayers; - } else { - // Interior, exterior or between-glass shade, screen or blind in place - TotGlassLayers = state.dataConstruction->Construct(constrNumSh).TotGlassLayers; - } - state.dataHeatBal->SurfWinSWwinAbsTotalReport(surfNum) = 0.0; - state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) = 0.0; - state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) = 0.0; - for (int lay = 1; lay <= TotGlassLayers; ++lay) { - // Initial Transmitted Diffuse Solar Absorbed on Inside of Surface[W] - state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) += - state.dataHeatBal->SurfWinInitialDifSolwinAbs(surfNum, lay) * surface.Area; - // Total Shortwave Radiation Absorbed on Inside of Surface[W] - state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) += state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, lay) * surface.Area; - // Total Shortwave Absorbed:All solid Layers[W] - state.dataHeatBal->SurfWinSWwinAbsTotalReport(surfNum) += state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, lay) * surface.Area; - } + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurf = thisSpace.WindowSurfaceFirst; + int const lastSurf = thisSpace.WindowSurfaceLast; + for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { + auto &surface(state.dataSurface->Surface(surfNum)); + state.dataHeatBal->SurfWinInitialDifSolInTransReport(surfNum) = + state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(surfNum) * surface.Area; + + // Absorbed short wave radiation + int TotGlassLayers; + int const constrNum = state.dataSurface->SurfActiveConstruction(surfNum); + int const constrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(surfNum); + WinShadingType ShadeFlag = state.dataSurface->SurfWinShadingFlag(surfNum); + if (state.dataSurface->SurfWinWindowModelType(surfNum) == WindowModel::EQL) { + TotGlassLayers = state.dataWindowEquivLayer->CFS(state.dataConstruction->Construct(constrNum).EQLConsPtr).NL; + } else if (state.dataSurface->SurfWinWindowModelType(surfNum) == WindowModel::BSDF) { + TotGlassLayers = state.dataConstruction->Construct(constrNum).TotSolidLayers; + } else if (NOT_SHADED(ShadeFlag) || ShadeFlag == WinShadingType::SwitchableGlazing) { + TotGlassLayers = state.dataConstruction->Construct(constrNum).TotGlassLayers; + } else { + // Interior, exterior or between-glass shade, screen or blind in place + TotGlassLayers = state.dataConstruction->Construct(constrNumSh).TotGlassLayers; + } + state.dataHeatBal->SurfWinSWwinAbsTotalReport(surfNum) = 0.0; + state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) = 0.0; + state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) = 0.0; + for (int lay = 1; lay <= TotGlassLayers; ++lay) { + // Initial Transmitted Diffuse Solar Absorbed on Inside of Surface[W] + state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) += + state.dataHeatBal->SurfWinInitialDifSolwinAbs(surfNum, lay) * surface.Area; + // Total Shortwave Radiation Absorbed on Inside of Surface[W] + state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) += state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, lay) * surface.Area; + // Total Shortwave Absorbed:All solid Layers[W] + state.dataHeatBal->SurfWinSWwinAbsTotalReport(surfNum) += state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, lay) * surface.Area; + } - // Window heat gain/loss - if (state.dataSurface->SurfWinHeatGain(surfNum) >= 0.0) { - state.dataSurface->SurfWinHeatGainRep(surfNum) = state.dataSurface->SurfWinHeatGain(surfNum); - state.dataSurface->SurfWinHeatGainRepEnergy(surfNum) = - state.dataSurface->SurfWinHeatGainRep(surfNum) * state.dataGlobal->TimeStepZoneSec; - } else { - state.dataSurface->SurfWinHeatLossRep(surfNum) = -state.dataSurface->SurfWinHeatGain(surfNum); - state.dataSurface->SurfWinHeatLossRepEnergy(surfNum) = - state.dataSurface->SurfWinHeatLossRep(surfNum) * state.dataGlobal->TimeStepZoneSec; - } - state.dataSurface->SurfWinHeatTransferRepEnergy(surfNum) = - state.dataSurface->SurfWinHeatGain(surfNum) * state.dataGlobal->TimeStepZoneSec; - if (state.dataSurface->SurfWinOriginalClass(surfNum) == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device - int pipeNum = state.dataSurface->SurfWinTDDPipeNum(surfNum); - state.dataDaylightingDevicesData->TDDPipe(pipeNum).HeatGain = state.dataSurface->SurfWinHeatGainRep(surfNum); - state.dataDaylightingDevicesData->TDDPipe(pipeNum).HeatLoss = state.dataSurface->SurfWinHeatLossRep(surfNum); + // Window heat gain/loss + if (state.dataSurface->SurfWinHeatGain(surfNum) >= 0.0) { + state.dataSurface->SurfWinHeatGainRep(surfNum) = state.dataSurface->SurfWinHeatGain(surfNum); + state.dataSurface->SurfWinHeatGainRepEnergy(surfNum) = + state.dataSurface->SurfWinHeatGainRep(surfNum) * state.dataGlobal->TimeStepZoneSec; + } else { + state.dataSurface->SurfWinHeatLossRep(surfNum) = -state.dataSurface->SurfWinHeatGain(surfNum); + state.dataSurface->SurfWinHeatLossRepEnergy(surfNum) = + state.dataSurface->SurfWinHeatLossRep(surfNum) * state.dataGlobal->TimeStepZoneSec; + } + state.dataSurface->SurfWinHeatTransferRepEnergy(surfNum) = + state.dataSurface->SurfWinHeatGain(surfNum) * state.dataGlobal->TimeStepZoneSec; + if (state.dataSurface->SurfWinOriginalClass(surfNum) == DataSurfaces::SurfaceClass::TDD_Diffuser) { // Tubular daylighting device + int pipeNum = state.dataSurface->SurfWinTDDPipeNum(surfNum); + state.dataDaylightingDevicesData->TDDPipe(pipeNum).HeatGain = state.dataSurface->SurfWinHeatGainRep(surfNum); + state.dataDaylightingDevicesData->TDDPipe(pipeNum).HeatLoss = state.dataSurface->SurfWinHeatLossRep(surfNum); + } } } } @@ -6464,82 +6538,85 @@ void ReportSurfaceHeatBalance(EnergyPlusData &state) // Opaque heat transfer surfaces for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceFirst; - int const lastSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceLast; - for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - auto &surface(state.dataSurface->Surface(surfNum)); - - state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) * surface.Area; - state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(surfNum) = - state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(surfNum) * state.dataGlobal->TimeStepZoneSec; - - state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(surfNum) * surface.Area; - state.dataHeatBalSurf->SurfQRadSolarInReport(surfNum) = - state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum) * state.dataGlobal->TimeStepZoneSec; - - state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum) * surface.Area; - state.dataHeatBalSurf->SurfQRadLightsInReport(surfNum) = - state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum) * state.dataGlobal->TimeStepZoneSec; - - // Initial Transmitted Diffuse Solar Absorbed on Inside of Surface[W] - state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) = state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(surfNum) * surface.Area; - // Total Shortwave Radiation Absorbed on Inside of Surface[W] - state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) * surface.Area; - - // inside face conduction updates - state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) = state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) * surface.Area; - state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(surfNum) = - state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec; - state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(surfNum) = 0.0; - state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(surfNum) = 0.0; - if (state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) >= 0.0) { - state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum); - } else { - state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum); + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst; + int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast; + for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { + auto &surface(state.dataSurface->Surface(surfNum)); + + state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWOutAbs(surfNum) * surface.Area; + state.dataHeatBal->SurfOpaqSWOutAbsEnergyReport(surfNum) = + state.dataHeatBal->SurfOpaqSWOutAbsTotalReport(surfNum) * state.dataGlobal->TimeStepZoneSec; + + state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadSolarInRepPerArea(surfNum) * surface.Area; + state.dataHeatBalSurf->SurfQRadSolarInReport(surfNum) = + state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum) * state.dataGlobal->TimeStepZoneSec; + + state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum) = state.dataHeatBalSurf->SurfQdotRadLightsInPerArea(surfNum) * surface.Area; + state.dataHeatBalSurf->SurfQRadLightsInReport(surfNum) = + state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum) * state.dataGlobal->TimeStepZoneSec; + + // Initial Transmitted Diffuse Solar Absorbed on Inside of Surface[W] + state.dataHeatBal->SurfInitialDifSolInAbsReport(surfNum) = state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(surfNum) * surface.Area; + // Total Shortwave Radiation Absorbed on Inside of Surface[W] + state.dataHeatBal->SurfSWInAbsTotalReport(surfNum) = state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) * surface.Area; + + // inside face conduction updates + state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) = state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) * surface.Area; + state.dataHeatBalSurf->SurfOpaqInsFaceCondEnergy(surfNum) = + state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec; + state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(surfNum) = 0.0; + state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(surfNum) = 0.0; + if (state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) >= 0.0) { + state.dataHeatBalSurf->SurfOpaqInsFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum); + } else { + state.dataHeatBalSurf->SurfOpaqInsFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum); + } + + // outside face conduction updates + state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) = surface.Area * state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum); + state.dataHeatBalSurf->SurfOpaqOutFaceCondEnergy(surfNum) = + state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec; + state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(surfNum) = 0.0; + state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(surfNum) = 0.0; + if (state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) >= 0.0) { + state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum); + } else { + state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum); + } } + for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { + // do average surface conduction updates + + state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) = + (state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) - state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum)) / 2.0; + state.dataHeatBalSurf->SurfOpaqAvgFaceCondFlux(surfNum) = + (state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) - state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum)) / 2.0; + state.dataHeatBalSurf->SurfOpaqAvgFaceCondEnergy(surfNum) = + state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec; + state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(surfNum) = 0.0; + state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(surfNum) = 0.0; + if (state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) >= 0.0) { + state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum); + } else { + state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum); + } - // outside face conduction updates - state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) = surface.Area * state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum); - state.dataHeatBalSurf->SurfOpaqOutFaceCondEnergy(surfNum) = - state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec; - state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(surfNum) = 0.0; - state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(surfNum) = 0.0; - if (state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum) >= 0.0) { - state.dataHeatBalSurf->SurfOpaqExtFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum); - } else { - state.dataHeatBalSurf->SurfOpaqExtFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum); - } - } - for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - // do average surface conduction updates - - state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) = - (state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) - state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum)) / 2.0; - state.dataHeatBalSurf->SurfOpaqAvgFaceCondFlux(surfNum) = - (state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) - state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum)) / 2.0; - state.dataHeatBalSurf->SurfOpaqAvgFaceCondEnergy(surfNum) = - state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) * state.dataGlobal->TimeStepZoneSec; - state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(surfNum) = 0.0; - state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(surfNum) = 0.0; - if (state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum) >= 0.0) { - state.dataHeatBalSurf->SurfOpaqAvgFaceCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum); - } else { - state.dataHeatBalSurf->SurfOpaqAvgFaceCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqAvgFaceCond(surfNum); - } - - // do surface storage rate updates - state.dataHeatBalSurf->SurfOpaqStorageCondFlux(surfNum) = - -(state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) + state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum)); - state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) = - -(state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) + state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum)); - state.dataHeatBalSurf->SurfOpaqStorageCondEnergy(surfNum) = - state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) * state.dataGlobal->TimeStepZoneSec; - state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(surfNum) = 0.0; - state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(surfNum) = 0.0; - if (state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) >= 0.0) { - state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum); - } else { - state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum); + // do surface storage rate updates + state.dataHeatBalSurf->SurfOpaqStorageCondFlux(surfNum) = + -(state.dataHeatBalSurf->SurfOpaqInsFaceCondFlux(surfNum) + state.dataHeatBalSurf->SurfOpaqOutFaceCondFlux(surfNum)); + state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) = + -(state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum) + state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum)); + state.dataHeatBalSurf->SurfOpaqStorageCondEnergy(surfNum) = + state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) * state.dataGlobal->TimeStepZoneSec; + state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(surfNum) = 0.0; + state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(surfNum) = 0.0; + if (state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum) >= 0.0) { + state.dataHeatBalSurf->SurfOpaqStorageCondGainRep(surfNum) = state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum); + } else { + state.dataHeatBalSurf->SurfOpaqStorageCondLossRep(surfNum) = -state.dataHeatBalSurf->SurfOpaqStorageCond(surfNum); + } } } } @@ -6547,27 +6624,30 @@ void ReportSurfaceHeatBalance(EnergyPlusData &state) if (state.dataGlobal->ZoneSizingCalc && state.dataGlobal->CompLoadReportIsReq) { int TimeStepInDay = (state.dataGlobal->HourOfDay - 1) * state.dataGlobal->NumOfTimeStepInHour + state.dataGlobal->TimeStep; for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int firstSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceFirst; - int lastSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceLast; - for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - state.dataOutRptTab->lightSWRadSeq(state.dataSize->CurOverallSimDay, TimeStepInDay, surfNum) = - state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum); - state.dataOutRptTab->feneSolarRadSeq(state.dataSize->CurOverallSimDay, TimeStepInDay, surfNum) = - state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum); - } - firstSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrWinSurfaceFirst; - lastSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrWinSurfaceLast; - for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - auto &surface(state.dataSurface->Surface(surfNum)); - if (!state.dataGlobal->WarmupFlag) { - if (state.dataGlobal->isPulseZoneSizing) { - state.dataOutRptTab->loadConvectedWithPulse(state.dataSize->CurOverallSimDay, TimeStepInDay, surfNum) = - state.dataHeatBalSurf->SurfQdotConvInRep(surfNum); - } else { - state.dataOutRptTab->loadConvectedNormal(state.dataSize->CurOverallSimDay, TimeStepInDay, surfNum) = - state.dataHeatBalSurf->SurfQdotConvInRep(surfNum); - state.dataOutRptTab->netSurfRadSeq(state.dataSize->CurOverallSimDay, TimeStepInDay, surfNum) = - state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) * surface.Area; + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst; + int lastSurf = thisSpace.OpaqOrIntMassSurfaceLast; + for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { + state.dataOutRptTab->lightSWRadSeq(state.dataSize->CurOverallSimDay, TimeStepInDay, surfNum) = + state.dataHeatBalSurf->SurfQdotRadLightsInRep(surfNum); + state.dataOutRptTab->feneSolarRadSeq(state.dataSize->CurOverallSimDay, TimeStepInDay, surfNum) = + state.dataHeatBalSurf->SurfQdotRadSolarInRep(surfNum); + } + firstSurf = thisSpace.OpaqOrWinSurfaceFirst; + lastSurf = thisSpace.OpaqOrWinSurfaceLast; + for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { + auto &surface(state.dataSurface->Surface(surfNum)); + if (!state.dataGlobal->WarmupFlag) { + if (state.dataGlobal->isPulseZoneSizing) { + state.dataOutRptTab->loadConvectedWithPulse(state.dataSize->CurOverallSimDay, TimeStepInDay, surfNum) = + state.dataHeatBalSurf->SurfQdotConvInRep(surfNum); + } else { + state.dataOutRptTab->loadConvectedNormal(state.dataSize->CurOverallSimDay, TimeStepInDay, surfNum) = + state.dataHeatBalSurf->SurfQdotConvInRep(surfNum); + state.dataOutRptTab->netSurfRadSeq(state.dataSize->CurOverallSimDay, TimeStepInDay, surfNum) = + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) * surface.Area; + } } } } @@ -6576,30 +6656,33 @@ void ReportSurfaceHeatBalance(EnergyPlusData &state) if (state.dataGlobal->DisplayAdvancedReportVariables) { for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceFirst; - int const lastSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceLast; - for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) += state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum); - state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) += state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum); - } - if (state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) >= 0.0) { - state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) = state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum); - state.dataHeatBal->ZnOpqSurfInsFaceCondGnRepEnrg(zoneNum) = - state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec; - } else { - state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) = -state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum); - state.dataHeatBal->ZnOpqSurfInsFaceCondLsRepEnrg(zoneNum) = - state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec; - } + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst; + int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast; + for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { + state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) += state.dataHeatBalSurf->SurfOpaqInsFaceCond(surfNum); + state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) += state.dataHeatBalSurf->SurfOpaqOutFaceCond(surfNum); + } + if (state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum) >= 0.0) { + state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) = state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum); + state.dataHeatBal->ZnOpqSurfInsFaceCondGnRepEnrg(zoneNum) = + state.dataHeatBal->ZoneOpaqSurfInsFaceCondGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec; + } else { + state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) = -state.dataHeatBal->ZoneOpaqSurfInsFaceCond(zoneNum); + state.dataHeatBal->ZnOpqSurfInsFaceCondLsRepEnrg(zoneNum) = + state.dataHeatBal->ZoneOpaqSurfInsFaceCondLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec; + } - if (state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) >= 0.0) { - state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) = state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum); - state.dataHeatBal->ZnOpqSurfExtFaceCondGnRepEnrg(zoneNum) = - state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec; - } else { - state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) = -state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum); - state.dataHeatBal->ZnOpqSurfExtFaceCondLsRepEnrg(zoneNum) = - state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec; + if (state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum) >= 0.0) { + state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) = state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum); + state.dataHeatBal->ZnOpqSurfExtFaceCondGnRepEnrg(zoneNum) = + state.dataHeatBal->ZoneOpaqSurfExtFaceCondGainRep(zoneNum) * state.dataGlobal->TimeStepZoneSec; + } else { + state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) = -state.dataHeatBal->ZoneOpaqSurfExtFaceCond(zoneNum); + state.dataHeatBal->ZnOpqSurfExtFaceCondLsRepEnrg(zoneNum) = + state.dataHeatBal->ZoneOpaqSurfExtFaceCondLossRep(zoneNum) * state.dataGlobal->TimeStepZoneSec; + } } } } @@ -6608,32 +6691,36 @@ void ReportSurfaceHeatBalance(EnergyPlusData &state) void ReportNonRepresentativeSurfaceResults(EnergyPlusData &state) { for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - // Heat transfer surfaces - int firstSurf = state.dataHeatBal->Zone(zoneNum).HTSurfaceFirst; - int lastSurf = state.dataHeatBal->Zone(zoneNum).HTSurfaceLast; - for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - auto &surface(state.dataSurface->Surface(surfNum)); - int repSurfNum = surface.RepresentativeCalcSurfNum; - if (surfNum != repSurfNum) { - state.dataSurface->SurfIntConvClassificationRpt(surfNum) = state.dataSurface->SurfIntConvClassificationRpt(repSurfNum); - state.dataSurface->SurfOutConvClassificationRpt(surfNum) = state.dataSurface->SurfOutConvClassificationRpt(repSurfNum); - } - } - - // Windows - if (state.dataGlobal->DisplayAdvancedReportVariables) { - firstSurf = state.dataHeatBal->Zone(zoneNum).WindowSurfaceFirst; - lastSurf = state.dataHeatBal->Zone(zoneNum).WindowSurfaceLast; + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + // Heat transfer surfaces + int firstSurf = thisSpace.HTSurfaceFirst; + int lastSurf = thisSpace.HTSurfaceLast; for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { auto &surface(state.dataSurface->Surface(surfNum)); int repSurfNum = surface.RepresentativeCalcSurfNum; if (surfNum != repSurfNum) { - auto areaRatio = surface.Area / state.dataSurface->Surface(surfNum).Area; - state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) = - state.dataSurface->SurfWinGainConvGlazToZoneRep(repSurfNum) * areaRatio; - state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = state.dataSurface->SurfWinGainIRGlazToZoneRep(repSurfNum) * areaRatio; - state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) = - state.dataSurface->SurfWinLossSWZoneToOutWinRep(repSurfNum) * areaRatio; + state.dataSurface->SurfIntConvClassificationRpt(surfNum) = state.dataSurface->SurfIntConvClassificationRpt(repSurfNum); + state.dataSurface->SurfOutConvClassificationRpt(surfNum) = state.dataSurface->SurfOutConvClassificationRpt(repSurfNum); + } + } + + // Windows + if (state.dataGlobal->DisplayAdvancedReportVariables) { + firstSurf = thisSpace.WindowSurfaceFirst; + lastSurf = thisSpace.WindowSurfaceLast; + for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { + auto &surface(state.dataSurface->Surface(surfNum)); + int repSurfNum = surface.RepresentativeCalcSurfNum; + if (surfNum != repSurfNum) { + auto areaRatio = surface.Area / state.dataSurface->Surface(surfNum).Area; + state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) = + state.dataSurface->SurfWinGainConvGlazToZoneRep(repSurfNum) * areaRatio; + state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = + state.dataSurface->SurfWinGainIRGlazToZoneRep(repSurfNum) * areaRatio; + state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) = + state.dataSurface->SurfWinLossSWZoneToOutWinRep(repSurfNum) * areaRatio; + } } } } @@ -6692,7 +6779,6 @@ void CalcHeatBalanceOutsideSurf(EnergyPlusData &state, // Using/Aliasing using namespace DataEnvironment; - using namespace DataHeatBalFanSys; using namespace DataHeatBalance; using namespace DataHeatBalSurface; using namespace DataSurfaces; @@ -6755,428 +6841,477 @@ void CalcHeatBalanceOutsideSurf(EnergyPlusData &state, } for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces... - for (int SurfNum = state.dataHeatBal->Zone(zoneNum).HTSurfaceFirst; SurfNum <= state.dataHeatBal->Zone(zoneNum).HTSurfaceLast; ++SurfNum) { - if (Surface(SurfNum).Class == SurfaceClass::Window) continue; - if (present(ZoneToResimulate)) { - if ((zoneNum != ZoneToResimulate) && (state.dataSurface->SurfAdjacentZone(SurfNum) != ZoneToResimulate)) { - continue; // skip surfaces that are not associated with this zone - } - } - // Interior windows in partitions use "normal" heat balance calculations - // For rest, Outside surface temp of windows not needed in Window5 calculation approach. - // Window layer temperatures are calculated in CalcHeatBalanceInsideSurf - - // Initializations for this surface - int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); - Real64 HMovInsul = 0.0; // "Convection" coefficient of movable insulation - Real64 HSky = 0.0; // "Convection" coefficient from sky to surface - Real64 HGround = 0.0; // "Convection" coefficient from ground to surface - Real64 HAir = 0.0; // "Convection" coefficient from air to surface (radiation) - state.dataHeatBalSurf->SurfHcExt(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfHAirExt(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfHSkyExt(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfHGrdExt(SurfNum) = 0.0; - state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs(SurfNum) = 0.0; - - // Calculate heat extract due to additional heat flux source term as the surface boundary condition - - if (Surface(SurfNum).OutsideHeatSourceTermSchedule) { - state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) = - EnergyPlus::ScheduleManager::GetCurrentScheduleValue(state, Surface(SurfNum).OutsideHeatSourceTermSchedule); - } - - // Calculate the current outside surface temperature TH(SurfNum,1,1) for the - // various different boundary conditions - switch (Surface(SurfNum).ExtBoundCond) { - case Ground: { // Surface in contact with ground - state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) = state.dataEnvrn->GroundTemp; - - // Set the only radiant system heat balance coefficient that is non-zero for this case - if (state.dataConstruction->Construct(ConstrNum).SourceSinkPresent) - state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum); - - // start HAMT - if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { - // Set variables used in the HAMT moisture balance - state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataEnvrn->GroundTemp; - state.dataMstBal->RhoVaporAirOut(SurfNum) = PsyRhovFnTdbRh(state, state.dataEnvrn->GroundTemp, 1.0, HBSurfManGroundHAMT); - state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit; - - state.dataMstBal->HMassConvExtFD(SurfNum) = - state.dataMstBal->HConvExtFD(SurfNum) / - ((PsyRhoAirFnPbTdbW( - state, - state.dataEnvrn->OutBaroPress, - state.dataEnvrn->GroundTemp, - PsyWFnTdbRhPb(state, state.dataEnvrn->GroundTemp, 1.0, state.dataEnvrn->OutBaroPress, RoutineNameGroundTemp)) + - state.dataMstBal->RhoVaporAirOut(SurfNum)) * - PsyCpAirFnW(state.dataEnvrn->OutHumRat)); - - state.dataMstBal->HSkyFD(SurfNum) = HSky; - state.dataMstBal->HGrndFD(SurfNum) = HGround; - state.dataMstBal->HAirFD(SurfNum) = HAir; - } - // end HAMT - - if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) { - // Set variables used in the FD moisture balance - state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataEnvrn->GroundTemp; - state.dataMstBal->RhoVaporAirOut(SurfNum) = PsyRhovFnTdbRhLBnd0C(state.dataEnvrn->GroundTemp, 1.0); - state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit; - state.dataMstBal->HMassConvExtFD(SurfNum) = - state.dataMstBal->HConvExtFD(SurfNum) / - ((PsyRhoAirFnPbTdbW( - state, - state.dataEnvrn->OutBaroPress, - state.dataEnvrn->GroundTemp, - PsyWFnTdbRhPb(state, state.dataEnvrn->GroundTemp, 1.0, state.dataEnvrn->OutBaroPress, RoutineNameGroundTemp)) + - state.dataMstBal->RhoVaporAirOut(SurfNum)) * - PsyCpAirFnW(state.dataEnvrn->OutHumRat)); - state.dataMstBal->HSkyFD(SurfNum) = HSky; - state.dataMstBal->HGrndFD(SurfNum) = HGround; - state.dataMstBal->HAirFD(SurfNum) = HAir; + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { + if (Surface(SurfNum).Class == SurfaceClass::Window) continue; + if (present(ZoneToResimulate)) { + if ((zoneNum != ZoneToResimulate) && (state.dataSurface->SurfAdjacentZone(SurfNum) != ZoneToResimulate)) { + continue; // skip surfaces that are not associated with this zone + } } - // Added for FCfactor grounds - } break; - case GroundFCfactorMethod: { // Surface in contact with ground - state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) = state.dataEnvrn->GroundTempFC; - - // Set the only radiant system heat balance coefficient that is non-zero for this case - if (state.dataConstruction->Construct(ConstrNum).SourceSinkPresent) - state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum); - - if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { - // Set variables used in the HAMT moisture balance - state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataEnvrn->GroundTempFC; - state.dataMstBal->RhoVaporAirOut(SurfNum) = PsyRhovFnTdbRh(state, state.dataEnvrn->GroundTempFC, 1.0, HBSurfManGroundHAMT); - state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit; - - state.dataMstBal->HMassConvExtFD(SurfNum) = - state.dataMstBal->HConvExtFD(SurfNum) / - ((PsyRhoAirFnPbTdbW( - state, - state.dataEnvrn->OutBaroPress, - state.dataEnvrn->GroundTempFC, - PsyWFnTdbRhPb(state, state.dataEnvrn->GroundTempFC, 1.0, state.dataEnvrn->OutBaroPress, RoutineNameGroundTempFC)) + - state.dataMstBal->RhoVaporAirOut(SurfNum)) * - PsyCpAirFnW(state.dataEnvrn->OutHumRat)); - - state.dataMstBal->HSkyFD(SurfNum) = HSky; - state.dataMstBal->HGrndFD(SurfNum) = HGround; - state.dataMstBal->HAirFD(SurfNum) = HAir; + // Interior windows in partitions use "normal" heat balance calculations + // For rest, Outside surface temp of windows not needed in Window5 calculation approach. + // Window layer temperatures are calculated in CalcHeatBalanceInsideSurf + + // Initializations for this surface + int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); + Real64 HMovInsul = 0.0; // "Convection" coefficient of movable insulation + Real64 HSky = 0.0; // "Convection" coefficient from sky to surface + Real64 HGround = 0.0; // "Convection" coefficient from ground to surface + Real64 HAir = 0.0; // "Convection" coefficient from air to surface (radiation) + state.dataHeatBalSurf->SurfHcExt(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfHAirExt(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) = 0.0; + state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs(SurfNum) = 0.0; + + // Calculate heat extract due to additional heat flux source term as the surface boundary condition + + if (Surface(SurfNum).OutsideHeatSourceTermSchedule) { + state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) = + EnergyPlus::ScheduleManager::GetCurrentScheduleValue(state, Surface(SurfNum).OutsideHeatSourceTermSchedule); } - if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) { - // Set variables used in the FD moisture balance - state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataEnvrn->GroundTempFC; - state.dataMstBal->RhoVaporAirOut(SurfNum) = PsyRhovFnTdbRhLBnd0C(state.dataEnvrn->GroundTempFC, 1.0); - state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit; - state.dataMstBal->HMassConvExtFD(SurfNum) = - state.dataMstBal->HConvExtFD(SurfNum) / - ((PsyRhoAirFnPbTdbW( - state, - state.dataEnvrn->OutBaroPress, - state.dataEnvrn->GroundTempFC, - PsyWFnTdbRhPb(state, state.dataEnvrn->GroundTempFC, 1.0, state.dataEnvrn->OutBaroPress, RoutineNameGroundTempFC)) + - state.dataMstBal->RhoVaporAirOut(SurfNum)) * - PsyCpAirFnW(state.dataEnvrn->OutHumRat)); - state.dataMstBal->HSkyFD(SurfNum) = HSky; - state.dataMstBal->HGrndFD(SurfNum) = HGround; - state.dataMstBal->HAirFD(SurfNum) = HAir; - } - } break; - case OtherSideCoefNoCalcExt: { - // Use Other Side Coefficients to determine the surface film coefficient and - // the exterior boundary condition temperature - - int OPtr = Surface(SurfNum).OSCPtr; - // Set surface temp from previous timestep - if (state.dataGlobal->BeginTimeStepFlag) { - state.dataSurface->OSC(OPtr).TOutsideSurfPast = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum); - } + // Calculate the current outside surface temperature TH(SurfNum,1,1) for the + // various different boundary conditions + switch (Surface(SurfNum).ExtBoundCond) { + case Ground: { // Surface in contact with ground + state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) = state.dataEnvrn->GroundTemp; - if (state.dataSurface->OSC(OPtr).ConstTempScheduleIndex != 0) { // Determine outside temperature from schedule - state.dataSurface->OSC(OPtr).ConstTemp = GetCurrentScheduleValue(state, state.dataSurface->OSC(OPtr).ConstTempScheduleIndex); - } + // Set the only radiant system heat balance coefficient that is non-zero for this case + if (state.dataConstruction->Construct(ConstrNum).SourceSinkPresent) + state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum); - // Allow for modification of TemperatureCoefficient with unitary sine wave. - Real64 ConstantTempCoef; // Temperature Coefficient as input or modified using sine wave COP mod - if (state.dataSurface->OSC(OPtr).SinusoidalConstTempCoef) { // Sine wave C4 - ConstantTempCoef = - std::sin(2 * DataGlobalConstants::Pi * state.dataGlobal->CurrentTime / state.dataSurface->OSC(OPtr).SinusoidPeriod); - } else { - ConstantTempCoef = state.dataSurface->OSC(OPtr).ConstTempCoef; - } + // start HAMT + if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { + // Set variables used in the HAMT moisture balance + state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataEnvrn->GroundTemp; + state.dataMstBal->RhoVaporAirOut(SurfNum) = PsyRhovFnTdbRh(state, state.dataEnvrn->GroundTemp, 1.0, HBSurfManGroundHAMT); + state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit; - state.dataSurface->OSC(OPtr).OSCTempCalc = - (state.dataSurface->OSC(OPtr).ZoneAirTempCoef * state.dataHeatBalFanSys->MAT(zoneNum) + - state.dataSurface->OSC(OPtr).ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(SurfNum) + - ConstantTempCoef * state.dataSurface->OSC(OPtr).ConstTemp + - state.dataSurface->OSC(OPtr).GroundTempCoef * state.dataEnvrn->GroundTemp + - state.dataSurface->OSC(OPtr).WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(SurfNum) * - state.dataSurface->SurfOutDryBulbTemp(SurfNum) + - state.dataSurface->OSC(OPtr).TPreviousCoef * state.dataSurface->OSC(OPtr).TOutsideSurfPast); - - // Enforce max/min limits if applicable - if (state.dataSurface->OSC(OPtr).MinLimitPresent) - state.dataSurface->OSC(OPtr).OSCTempCalc = - max(state.dataSurface->OSC(OPtr).MinTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc); - if (state.dataSurface->OSC(OPtr).MaxLimitPresent) - state.dataSurface->OSC(OPtr).OSCTempCalc = - min(state.dataSurface->OSC(OPtr).MaxTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc); - - state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) = state.dataSurface->OSC(OPtr).OSCTempCalc; - - // Set the only radiant system heat balance coefficient that is non-zero for this case - if (state.dataConstruction->Construct(ConstrNum).SourceSinkPresent) - state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum); - - if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD || - Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { - // Set variables used in the FD moisture balance and HAMT - state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum); - state.dataMstBal->RhoVaporAirOut(SurfNum) = - PsyRhovFnTdbWPb(state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress); - state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit; - state.dataMstBal->HMassConvExtFD(SurfNum) = - state.dataMstBal->HConvExtFD(SurfNum) / ((PsyRhoAirFnPbTdbW(state, - state.dataEnvrn->OutBaroPress, - state.dataMstBal->TempOutsideAirFD(SurfNum), - PsyWFnTdbRhPb(state, - state.dataMstBal->TempOutsideAirFD(SurfNum), - 1.0, - state.dataEnvrn->OutBaroPress, - RoutineNameOtherSideCoefNoCalcExt)) + - state.dataMstBal->RhoVaporAirOut(SurfNum)) * - PsyCpAirFnW(state.dataEnvrn->OutHumRat)); - state.dataMstBal->HSkyFD(SurfNum) = HSky; - state.dataMstBal->HGrndFD(SurfNum) = HGround; - state.dataMstBal->HAirFD(SurfNum) = HAir; - } - // This ends the calculations for this surface and goes on to the next SurfNum - } break; - case OtherSideCoefCalcExt: { // A surface with other side coefficients that define the outside environment - // First, set up the outside convection coefficient and the exterior temperature - // boundary condition for the surface - int OPtr = Surface(SurfNum).OSCPtr; - // Set surface temp from previous timestep - if (state.dataGlobal->BeginTimeStepFlag) { - state.dataSurface->OSC(OPtr).TOutsideSurfPast = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum); - } + state.dataMstBal->HMassConvExtFD(SurfNum) = + state.dataMstBal->HConvExtFD(SurfNum) / + ((PsyRhoAirFnPbTdbW( + state, + state.dataEnvrn->OutBaroPress, + state.dataEnvrn->GroundTemp, + PsyWFnTdbRhPb(state, state.dataEnvrn->GroundTemp, 1.0, state.dataEnvrn->OutBaroPress, RoutineNameGroundTemp)) + + state.dataMstBal->RhoVaporAirOut(SurfNum)) * + PsyCpAirFnW(state.dataEnvrn->OutHumRat)); - if (state.dataSurface->OSC(OPtr).ConstTempScheduleIndex != 0) { // Determine outside temperature from schedule - state.dataSurface->OSC(OPtr).ConstTemp = GetCurrentScheduleValue(state, state.dataSurface->OSC(OPtr).ConstTempScheduleIndex); - } + state.dataMstBal->HSkyFD(SurfNum) = HSky; + state.dataMstBal->HGrndFD(SurfNum) = HGround; + state.dataMstBal->HAirFD(SurfNum) = HAir; + } + // end HAMT - state.dataHeatBalSurf->SurfHcExt(SurfNum) = state.dataSurface->OSC(OPtr).SurfFilmCoef; + if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) { + // Set variables used in the FD moisture balance + state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataEnvrn->GroundTemp; + state.dataMstBal->RhoVaporAirOut(SurfNum) = PsyRhovFnTdbRhLBnd0C(state.dataEnvrn->GroundTemp, 1.0); + state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit; + state.dataMstBal->HMassConvExtFD(SurfNum) = + state.dataMstBal->HConvExtFD(SurfNum) / + ((PsyRhoAirFnPbTdbW( + state, + state.dataEnvrn->OutBaroPress, + state.dataEnvrn->GroundTemp, + PsyWFnTdbRhPb(state, state.dataEnvrn->GroundTemp, 1.0, state.dataEnvrn->OutBaroPress, RoutineNameGroundTemp)) + + state.dataMstBal->RhoVaporAirOut(SurfNum)) * + PsyCpAirFnW(state.dataEnvrn->OutHumRat)); + state.dataMstBal->HSkyFD(SurfNum) = HSky; + state.dataMstBal->HGrndFD(SurfNum) = HGround; + state.dataMstBal->HAirFD(SurfNum) = HAir; + } + // Added for FCfactor grounds + } break; + case GroundFCfactorMethod: { // Surface in contact with ground + state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) = state.dataEnvrn->GroundTempFC; - state.dataSurface->OSC(OPtr).OSCTempCalc = - (state.dataSurface->OSC(OPtr).ZoneAirTempCoef * state.dataHeatBalFanSys->MAT(zoneNum) + - state.dataSurface->OSC(OPtr).ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(SurfNum) + - state.dataSurface->OSC(OPtr).ConstTempCoef * state.dataSurface->OSC(OPtr).ConstTemp + - state.dataSurface->OSC(OPtr).GroundTempCoef * state.dataEnvrn->GroundTemp + - state.dataSurface->OSC(OPtr).WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(SurfNum) * - state.dataSurface->SurfOutDryBulbTemp(SurfNum) + - state.dataSurface->OSC(OPtr).TPreviousCoef * state.dataSurface->OSC(OPtr).TOutsideSurfPast); + // Set the only radiant system heat balance coefficient that is non-zero for this case + if (state.dataConstruction->Construct(ConstrNum).SourceSinkPresent) + state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum); - // Enforce max/min limits if applicable - if (state.dataSurface->OSC(OPtr).MinLimitPresent) - state.dataSurface->OSC(OPtr).OSCTempCalc = - max(state.dataSurface->OSC(OPtr).MinTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc); - if (state.dataSurface->OSC(OPtr).MaxLimitPresent) - state.dataSurface->OSC(OPtr).OSCTempCalc = - min(state.dataSurface->OSC(OPtr).MaxTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc); - - Real64 TempExt = state.dataSurface->OSC(OPtr).OSCTempCalc; - - // Set the only radiant system heat balance coefficient that is non-zero for this case - if (state.dataConstruction->Construct(ConstrNum).SourceSinkPresent) - state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum); - - if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD || - Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { - // Set variables used in the FD moisture balance and HAMT - state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt; - state.dataMstBal->RhoVaporAirOut(SurfNum) = - PsyRhovFnTdbWPb(state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress); - state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHcExt(SurfNum); - state.dataMstBal->HMassConvExtFD(SurfNum) = - state.dataMstBal->HConvExtFD(SurfNum) / ((PsyRhoAirFnPbTdbW(state, - state.dataEnvrn->OutBaroPress, - state.dataMstBal->TempOutsideAirFD(SurfNum), - PsyWFnTdbRhPb(state, - state.dataMstBal->TempOutsideAirFD(SurfNum), - 1.0, - state.dataEnvrn->OutBaroPress, - RoutineNameOtherSideCoefCalcExt)) + - state.dataMstBal->RhoVaporAirOut(SurfNum)) * - PsyCpAirFnW(state.dataEnvrn->OutHumRat)); - state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum); - state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum); - state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum); - } + if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { + // Set variables used in the HAMT moisture balance + state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataEnvrn->GroundTempFC; + state.dataMstBal->RhoVaporAirOut(SurfNum) = PsyRhovFnTdbRh(state, state.dataEnvrn->GroundTempFC, 1.0, HBSurfManGroundHAMT); + state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit; - // Call the outside surface temp calculation and pass the necessary terms - if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF || - Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) { - CalcOutsideSurfTemp(state, SurfNum, zoneNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag); - if (MovInsulErrorFlag) ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions."); - } - // This ends the calculations for this surface and goes on to the next SurfNum - } break; - case OtherSideCondModeledExt: { // A surface with other side conditions determined from seperate, dynamic component - // modeling that defines the "outside environment" - // First, set up the outside convection coefficient and the exterior temperature - // boundary condition for the surface - int OPtr = Surface(SurfNum).OSCMPtr; - // EMS overrides - if (state.dataSurface->OSCM(OPtr).EMSOverrideOnTConv) - state.dataSurface->OSCM(OPtr).TConv = state.dataSurface->OSCM(OPtr).EMSOverrideTConvValue; - if (state.dataSurface->OSCM(OPtr).EMSOverrideOnHConv) - state.dataSurface->OSCM(OPtr).HConv = state.dataSurface->OSCM(OPtr).EMSOverrideHConvValue; - if (state.dataSurface->OSCM(OPtr).EMSOverrideOnTRad) - state.dataSurface->OSCM(OPtr).TRad = state.dataSurface->OSCM(OPtr).EMSOverrideTRadValue; - if (state.dataSurface->OSCM(OPtr).EMSOverrideOnHrad) - state.dataSurface->OSCM(OPtr).HRad = state.dataSurface->OSCM(OPtr).EMSOverrideHradValue; - state.dataHeatBalSurf->SurfHcExt(SurfNum) = state.dataSurface->OSCM(OPtr).HConv; - - Real64 TempExt = state.dataSurface->OSCM(OPtr).TConv; - - // Set the only radiant system heat balance coefficient that is non-zero for this case - if (state.dataConstruction->Construct(ConstrNum).SourceSinkPresent) - state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum); - - if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD || - Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { - // Set variables used in the FD moisture balance and HAMT - state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt; - state.dataMstBal->RhoVaporAirOut(SurfNum) = - PsyRhovFnTdbWPb(state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress); - state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHcExt(SurfNum); - state.dataMstBal->HMassConvExtFD(SurfNum) = - state.dataMstBal->HConvExtFD(SurfNum) / - ((PsyRhoAirFnPbTdbW( - state, - state.dataEnvrn->OutBaroPress, - state.dataMstBal->TempOutsideAirFD(SurfNum), - PsyWFnTdbRhPb( - state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, state.dataEnvrn->OutBaroPress, RoutineNameOSCM)) + - state.dataMstBal->RhoVaporAirOut(SurfNum)) * - PsyCpAirFnW(state.dataEnvrn->OutHumRat)); - state.dataMstBal->HSkyFD(SurfNum) = state.dataSurface->OSCM(OPtr).HRad; // CR 8046, use sky term for surface to baffle IR - state.dataMstBal->HGrndFD(SurfNum) = 0.0; // CR 8046, null out and use only sky term for surface to baffle IR - state.dataMstBal->HAirFD(SurfNum) = 0.0; // CR 8046, null out and use only sky term for surface to baffle IR - } + state.dataMstBal->HMassConvExtFD(SurfNum) = + state.dataMstBal->HConvExtFD(SurfNum) / + ((PsyRhoAirFnPbTdbW( + state, + state.dataEnvrn->OutBaroPress, + state.dataEnvrn->GroundTempFC, + PsyWFnTdbRhPb(state, state.dataEnvrn->GroundTempFC, 1.0, state.dataEnvrn->OutBaroPress, RoutineNameGroundTempFC)) + + state.dataMstBal->RhoVaporAirOut(SurfNum)) * + PsyCpAirFnW(state.dataEnvrn->OutHumRat)); - // Call the outside surface temp calculation and pass the necessary terms - if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF || - Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) { + state.dataMstBal->HSkyFD(SurfNum) = HSky; + state.dataMstBal->HGrndFD(SurfNum) = HGround; + state.dataMstBal->HAirFD(SurfNum) = HAir; + } - if (state.dataSurface->SurfExtCavityPresent(SurfNum)) { - CalcExteriorVentedCavity(state, SurfNum); + if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) { + // Set variables used in the FD moisture balance + state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataEnvrn->GroundTempFC; + state.dataMstBal->RhoVaporAirOut(SurfNum) = PsyRhovFnTdbRhLBnd0C(state.dataEnvrn->GroundTempFC, 1.0); + state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit; + state.dataMstBal->HMassConvExtFD(SurfNum) = + state.dataMstBal->HConvExtFD(SurfNum) / + ((PsyRhoAirFnPbTdbW( + state, + state.dataEnvrn->OutBaroPress, + state.dataEnvrn->GroundTempFC, + PsyWFnTdbRhPb(state, state.dataEnvrn->GroundTempFC, 1.0, state.dataEnvrn->OutBaroPress, RoutineNameGroundTempFC)) + + state.dataMstBal->RhoVaporAirOut(SurfNum)) * + PsyCpAirFnW(state.dataEnvrn->OutHumRat)); + state.dataMstBal->HSkyFD(SurfNum) = HSky; + state.dataMstBal->HGrndFD(SurfNum) = HGround; + state.dataMstBal->HAirFD(SurfNum) = HAir; + } + } break; + case OtherSideCoefNoCalcExt: { + // Use Other Side Coefficients to determine the surface film coefficient and + // the exterior boundary condition temperature + + int OPtr = Surface(SurfNum).OSCPtr; + // Set surface temp from previous timestep + if (state.dataGlobal->BeginTimeStepFlag) { + state.dataSurface->OSC(OPtr).TOutsideSurfPast = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum); } - CalcOutsideSurfTemp(state, SurfNum, zoneNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag); - if (MovInsulErrorFlag) ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions."); + if (state.dataSurface->OSC(OPtr).ConstTempScheduleIndex != 0) { // Determine outside temperature from schedule + state.dataSurface->OSC(OPtr).ConstTemp = GetCurrentScheduleValue(state, state.dataSurface->OSC(OPtr).ConstTempScheduleIndex); + } - } else if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD || - Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { - if (state.dataSurface->SurfExtCavityPresent(SurfNum)) { - CalcExteriorVentedCavity(state, SurfNum); + // Allow for modification of TemperatureCoefficient with unitary sine wave. + Real64 ConstantTempCoef; // Temperature Coefficient as input or modified using sine wave COP mod + if (state.dataSurface->OSC(OPtr).SinusoidalConstTempCoef) { // Sine wave C4 + ConstantTempCoef = + std::sin(2 * DataGlobalConstants::Pi * state.dataGlobal->CurrentTime / state.dataSurface->OSC(OPtr).SinusoidPeriod); + } else { + ConstantTempCoef = state.dataSurface->OSC(OPtr).ConstTempCoef; } - } - // This ends the calculations for this surface and goes on to the next SurfNum - } break; - case ExternalEnvironment: { - // checking the EcoRoof presented in the external environment - // recompute each load by calling ecoroof - Real64 TempExt; + state.dataSurface->OSC(OPtr).OSCTempCalc = + (state.dataSurface->OSC(OPtr).ZoneAirTempCoef * state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum).MAT + + state.dataSurface->OSC(OPtr).ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(SurfNum) + + ConstantTempCoef * state.dataSurface->OSC(OPtr).ConstTemp + + state.dataSurface->OSC(OPtr).GroundTempCoef * state.dataEnvrn->GroundTemp + + state.dataSurface->OSC(OPtr).WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(SurfNum) * + state.dataSurface->SurfOutDryBulbTemp(SurfNum) + + state.dataSurface->OSC(OPtr).TPreviousCoef * state.dataSurface->OSC(OPtr).TOutsideSurfPast); + + // Enforce max/min limits if applicable + if (state.dataSurface->OSC(OPtr).MinLimitPresent) + state.dataSurface->OSC(OPtr).OSCTempCalc = + max(state.dataSurface->OSC(OPtr).MinTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc); + if (state.dataSurface->OSC(OPtr).MaxLimitPresent) + state.dataSurface->OSC(OPtr).OSCTempCalc = + min(state.dataSurface->OSC(OPtr).MaxTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc); + + state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) = state.dataSurface->OSC(OPtr).OSCTempCalc; + + // Set the only radiant system heat balance coefficient that is non-zero for this case + if (state.dataConstruction->Construct(ConstrNum).SourceSinkPresent) + state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum); - if (state.dataSurface->SurfExtEcoRoof(SurfNum)) { - CalcEcoRoof(state, SurfNum, zoneNum, ConstrNum, TempExt); - continue; - } - // Roughness index of the exterior surface - DataSurfaces::SurfaceRoughness RoughSurf = state.dataHeatBalSurf->SurfRoughnessExt(SurfNum); - // Thermal absoptance of the exterior surface - Real64 AbsThermSurf = state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum); - HMovInsul = 0; - // Check for outside movable insulation - if (state.dataSurface->AnyMovableInsulation && state.dataHeatBalSurf->SurfMovInsulExtPresent(SurfNum)) { - HMovInsul = state.dataHeatBalSurf->SurfMovInsulHExt(SurfNum); - } + if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD || + Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { + // Set variables used in the FD moisture balance and HAMT + state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum); + state.dataMstBal->RhoVaporAirOut(SurfNum) = + PsyRhovFnTdbWPb(state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress); + state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBal->HighHConvLimit; + state.dataMstBal->HMassConvExtFD(SurfNum) = + state.dataMstBal->HConvExtFD(SurfNum) / ((PsyRhoAirFnPbTdbW(state, + state.dataEnvrn->OutBaroPress, + state.dataMstBal->TempOutsideAirFD(SurfNum), + PsyWFnTdbRhPb(state, + state.dataMstBal->TempOutsideAirFD(SurfNum), + 1.0, + state.dataEnvrn->OutBaroPress, + RoutineNameOtherSideCoefNoCalcExt)) + + state.dataMstBal->RhoVaporAirOut(SurfNum)) * + PsyCpAirFnW(state.dataEnvrn->OutHumRat)); + state.dataMstBal->HSkyFD(SurfNum) = HSky; + state.dataMstBal->HGrndFD(SurfNum) = HGround; + state.dataMstBal->HAirFD(SurfNum) = HAir; + } + // This ends the calculations for this surface and goes on to the next SurfNum + } break; + case OtherSideCoefCalcExt: { // A surface with other side coefficients that define the outside environment + // First, set up the outside convection coefficient and the exterior temperature + // boundary condition for the surface + int OPtr = Surface(SurfNum).OSCPtr; + // Set surface temp from previous timestep + if (state.dataGlobal->BeginTimeStepFlag) { + state.dataSurface->OSC(OPtr).TOutsideSurfPast = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum); + } - // Check for exposure to wind (exterior environment) - if (Surface(SurfNum).ExtWind) { + if (state.dataSurface->OSC(OPtr).ConstTempScheduleIndex != 0) { // Determine outside temperature from schedule + state.dataSurface->OSC(OPtr).ConstTemp = GetCurrentScheduleValue(state, state.dataSurface->OSC(OPtr).ConstTempScheduleIndex); + } - // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in subroutine) - InitExteriorConvectionCoeff(state, - SurfNum, - HMovInsul, - RoughSurf, - AbsThermSurf, - state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum), - state.dataHeatBalSurf->SurfHcExt(SurfNum), - state.dataHeatBalSurf->SurfHSkyExt(SurfNum), - state.dataHeatBalSurf->SurfHGrdExt(SurfNum), - state.dataHeatBalSurf->SurfHAirExt(SurfNum)); + state.dataHeatBalSurf->SurfHcExt(SurfNum) = state.dataSurface->OSC(OPtr).SurfFilmCoef; - if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside surface gets wet + state.dataSurface->OSC(OPtr).OSCTempCalc = + (state.dataSurface->OSC(OPtr).ZoneAirTempCoef * state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum).MAT + + state.dataSurface->OSC(OPtr).ExtDryBulbCoef * state.dataSurface->SurfOutDryBulbTemp(SurfNum) + + state.dataSurface->OSC(OPtr).ConstTempCoef * state.dataSurface->OSC(OPtr).ConstTemp + + state.dataSurface->OSC(OPtr).GroundTempCoef * state.dataEnvrn->GroundTemp + + state.dataSurface->OSC(OPtr).WindSpeedCoef * state.dataSurface->SurfOutWindSpeed(SurfNum) * + state.dataSurface->SurfOutDryBulbTemp(SurfNum) + + state.dataSurface->OSC(OPtr).TPreviousCoef * state.dataSurface->OSC(OPtr).TOutsideSurfPast); + + // Enforce max/min limits if applicable + if (state.dataSurface->OSC(OPtr).MinLimitPresent) + state.dataSurface->OSC(OPtr).OSCTempCalc = + max(state.dataSurface->OSC(OPtr).MinTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc); + if (state.dataSurface->OSC(OPtr).MaxLimitPresent) + state.dataSurface->OSC(OPtr).OSCTempCalc = + min(state.dataSurface->OSC(OPtr).MaxTempLimit, state.dataSurface->OSC(OPtr).OSCTempCalc); + + Real64 TempExt = state.dataSurface->OSC(OPtr).OSCTempCalc; + + // Set the only radiant system heat balance coefficient that is non-zero for this case + if (state.dataConstruction->Construct(ConstrNum).SourceSinkPresent) + state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum); + + if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD || + Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { + // Set variables used in the FD moisture balance and HAMT + state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt; + state.dataMstBal->RhoVaporAirOut(SurfNum) = + PsyRhovFnTdbWPb(state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress); + state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHcExt(SurfNum); + state.dataMstBal->HMassConvExtFD(SurfNum) = + state.dataMstBal->HConvExtFD(SurfNum) / ((PsyRhoAirFnPbTdbW(state, + state.dataEnvrn->OutBaroPress, + state.dataMstBal->TempOutsideAirFD(SurfNum), + PsyWFnTdbRhPb(state, + state.dataMstBal->TempOutsideAirFD(SurfNum), + 1.0, + state.dataEnvrn->OutBaroPress, + RoutineNameOtherSideCoefCalcExt)) + + state.dataMstBal->RhoVaporAirOut(SurfNum)) * + PsyCpAirFnW(state.dataEnvrn->OutHumRat)); + state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum); + state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum); + state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum); + } + + // Call the outside surface temp calculation and pass the necessary terms + if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF || + Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) { + CalcOutsideSurfTemp(state, SurfNum, zoneNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag); + if (MovInsulErrorFlag) ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions."); + } + // This ends the calculations for this surface and goes on to the next SurfNum + } break; + case OtherSideCondModeledExt: { // A surface with other side conditions determined from seperate, dynamic component + // modeling that defines the "outside environment" + // First, set up the outside convection coefficient and the exterior temperature + // boundary condition for the surface + int OPtr = Surface(SurfNum).OSCMPtr; + // EMS overrides + if (state.dataSurface->OSCM(OPtr).EMSOverrideOnTConv) + state.dataSurface->OSCM(OPtr).TConv = state.dataSurface->OSCM(OPtr).EMSOverrideTConvValue; + if (state.dataSurface->OSCM(OPtr).EMSOverrideOnHConv) + state.dataSurface->OSCM(OPtr).HConv = state.dataSurface->OSCM(OPtr).EMSOverrideHConvValue; + if (state.dataSurface->OSCM(OPtr).EMSOverrideOnTRad) + state.dataSurface->OSCM(OPtr).TRad = state.dataSurface->OSCM(OPtr).EMSOverrideTRadValue; + if (state.dataSurface->OSCM(OPtr).EMSOverrideOnHrad) + state.dataSurface->OSCM(OPtr).HRad = state.dataSurface->OSCM(OPtr).EMSOverrideHradValue; + state.dataHeatBalSurf->SurfHcExt(SurfNum) = state.dataSurface->OSCM(OPtr).HConv; + + Real64 TempExt = state.dataSurface->OSCM(OPtr).TConv; + + // Set the only radiant system heat balance coefficient that is non-zero for this case + if (state.dataConstruction->Construct(ConstrNum).SourceSinkPresent) + state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum); + + if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD || + Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { + // Set variables used in the FD moisture balance and HAMT + state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt; + state.dataMstBal->RhoVaporAirOut(SurfNum) = + PsyRhovFnTdbWPb(state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress); + state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHcExt(SurfNum); + state.dataMstBal->HMassConvExtFD(SurfNum) = + state.dataMstBal->HConvExtFD(SurfNum) / + ((PsyRhoAirFnPbTdbW( + state, + state.dataEnvrn->OutBaroPress, + state.dataMstBal->TempOutsideAirFD(SurfNum), + PsyWFnTdbRhPb( + state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, state.dataEnvrn->OutBaroPress, RoutineNameOSCM)) + + state.dataMstBal->RhoVaporAirOut(SurfNum)) * + PsyCpAirFnW(state.dataEnvrn->OutHumRat)); + state.dataMstBal->HSkyFD(SurfNum) = state.dataSurface->OSCM(OPtr).HRad; // CR 8046, use sky term for surface to baffle IR + state.dataMstBal->HGrndFD(SurfNum) = 0.0; // CR 8046, null out and use only sky term for surface to baffle IR + state.dataMstBal->HAirFD(SurfNum) = 0.0; // CR 8046, null out and use only sky term for surface to baffle IR + } - if (state.dataSurface->SurfExtConvCoeffIndex(SurfNum) <= 0) { // Reset SurfHcExt because of wetness - state.dataHeatBalSurf->SurfHcExt(SurfNum) = 1000.0; - } else { // User set - state.dataHeatBalSurf->SurfHcExt(SurfNum) = SetExtConvectionCoeff(state, SurfNum); + // Call the outside surface temp calculation and pass the necessary terms + if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF || + Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) { + + if (state.dataSurface->SurfExtCavityPresent(SurfNum)) { + CalcExteriorVentedCavity(state, SurfNum); } - TempExt = state.dataSurface->SurfOutWetBulbTemp(SurfNum); + CalcOutsideSurfTemp(state, SurfNum, zoneNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag); + if (MovInsulErrorFlag) ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions."); - // start HAMT - if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { - // Set variables used in the HAMT moisture balance - state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt; - state.dataMstBal->RhoVaporAirOut(SurfNum) = - PsyRhovFnTdbRh(state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, HBSurfManRainHAMT); - state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHcExt(SurfNum); - state.dataMstBal->HMassConvExtFD(SurfNum) = - state.dataMstBal->HConvExtFD(SurfNum) / ((PsyRhoAirFnPbTdbW(state, - state.dataEnvrn->OutBaroPress, - state.dataMstBal->TempOutsideAirFD(SurfNum), - PsyWFnTdbRhPb(state, - state.dataMstBal->TempOutsideAirFD(SurfNum), - 1.0, - state.dataEnvrn->OutBaroPress, - RoutineNameExtEnvWetSurf)) + - state.dataMstBal->RhoVaporAirOut(SurfNum)) * - PsyCpAirFnW(state.dataEnvrn->OutHumRat)); - state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum); - state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum); - state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum); + } else if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD || + Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { + if (state.dataSurface->SurfExtCavityPresent(SurfNum)) { + CalcExteriorVentedCavity(state, SurfNum); } - // end HAMT - if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) { - // Set variables used in the FD moisture balance - state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt; - state.dataMstBal->RhoVaporAirOut(SurfNum) = PsyRhovFnTdbRhLBnd0C(state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0); - state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHcExt(SurfNum); - state.dataMstBal->HMassConvExtFD(SurfNum) = - state.dataMstBal->HConvExtFD(SurfNum) / ((PsyRhoAirFnPbTdbW(state, - state.dataEnvrn->OutBaroPress, - state.dataMstBal->TempOutsideAirFD(SurfNum), - PsyWFnTdbRhPb(state, - state.dataMstBal->TempOutsideAirFD(SurfNum), - 1.0, - state.dataEnvrn->OutBaroPress, - RoutineNameExtEnvWetSurf)) + - state.dataMstBal->RhoVaporAirOut(SurfNum)) * - PsyCpAirFnW(state.dataEnvrn->OutHumRat)); - state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum); - state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum); - state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum); + } + // This ends the calculations for this surface and goes on to the next SurfNum + } break; + case ExternalEnvironment: { + // checking the EcoRoof presented in the external environment + // recompute each load by calling ecoroof + + Real64 TempExt; + + if (state.dataSurface->SurfExtEcoRoof(SurfNum)) { + CalcEcoRoof(state, SurfNum, zoneNum, ConstrNum, TempExt); + continue; + } + // Roughness index of the exterior surface + DataSurfaces::SurfaceRoughness RoughSurf = state.dataHeatBalSurf->SurfRoughnessExt(SurfNum); + // Thermal absoptance of the exterior surface + Real64 AbsThermSurf = state.dataHeatBalSurf->SurfAbsThermalExt(SurfNum); + HMovInsul = 0; + // Check for outside movable insulation + if (state.dataSurface->AnyMovableInsulation && state.dataHeatBalSurf->SurfMovInsulExtPresent(SurfNum)) { + HMovInsul = state.dataHeatBalSurf->SurfMovInsulHExt(SurfNum); + } + + // Check for exposure to wind (exterior environment) + if (Surface(SurfNum).ExtWind) { + + // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in subroutine) + InitExteriorConvectionCoeff(state, + SurfNum, + HMovInsul, + RoughSurf, + AbsThermSurf, + state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum), + state.dataHeatBalSurf->SurfHcExt(SurfNum), + state.dataHeatBalSurf->SurfHSkyExt(SurfNum), + state.dataHeatBalSurf->SurfHGrdExt(SurfNum), + state.dataHeatBalSurf->SurfHAirExt(SurfNum)); + + if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside surface gets wet + + if (state.dataSurface->SurfExtConvCoeffIndex(SurfNum) <= 0) { // Reset SurfHcExt because of wetness + state.dataHeatBalSurf->SurfHcExt(SurfNum) = 1000.0; + } else { // User set + state.dataHeatBalSurf->SurfHcExt(SurfNum) = SetExtConvectionCoeff(state, SurfNum); + } + + TempExt = state.dataSurface->SurfOutWetBulbTemp(SurfNum); + + // start HAMT + if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { + // Set variables used in the HAMT moisture balance + state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt; + state.dataMstBal->RhoVaporAirOut(SurfNum) = + PsyRhovFnTdbRh(state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, HBSurfManRainHAMT); + state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHcExt(SurfNum); + state.dataMstBal->HMassConvExtFD(SurfNum) = + state.dataMstBal->HConvExtFD(SurfNum) / + ((PsyRhoAirFnPbTdbW(state, + state.dataEnvrn->OutBaroPress, + state.dataMstBal->TempOutsideAirFD(SurfNum), + PsyWFnTdbRhPb(state, + state.dataMstBal->TempOutsideAirFD(SurfNum), + 1.0, + state.dataEnvrn->OutBaroPress, + RoutineNameExtEnvWetSurf)) + + state.dataMstBal->RhoVaporAirOut(SurfNum)) * + PsyCpAirFnW(state.dataEnvrn->OutHumRat)); + state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum); + state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum); + state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum); + } + // end HAMT + if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) { + // Set variables used in the FD moisture balance + state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt; + state.dataMstBal->RhoVaporAirOut(SurfNum) = PsyRhovFnTdbRhLBnd0C(state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0); + state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHcExt(SurfNum); + state.dataMstBal->HMassConvExtFD(SurfNum) = + state.dataMstBal->HConvExtFD(SurfNum) / + ((PsyRhoAirFnPbTdbW(state, + state.dataEnvrn->OutBaroPress, + state.dataMstBal->TempOutsideAirFD(SurfNum), + PsyWFnTdbRhPb(state, + state.dataMstBal->TempOutsideAirFD(SurfNum), + 1.0, + state.dataEnvrn->OutBaroPress, + RoutineNameExtEnvWetSurf)) + + state.dataMstBal->RhoVaporAirOut(SurfNum)) * + PsyCpAirFnW(state.dataEnvrn->OutHumRat)); + state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum); + state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum); + state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum); + } + + } else { // Surface is dry, use the normal correlation + + TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum); + + if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD || + Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { + // Set variables used in the FD moisture balance and HAMT + state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt; + state.dataMstBal->RhoVaporAirOut(SurfNum) = PsyRhovFnTdbWPb( + state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress); + state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHcExt(SurfNum); + state.dataMstBal->HMassConvExtFD(SurfNum) = + state.dataMstBal->HConvExtFD(SurfNum) / + ((PsyRhoAirFnPbTdbW(state, + state.dataEnvrn->OutBaroPress, + state.dataMstBal->TempOutsideAirFD(SurfNum), + PsyWFnTdbRhPb(state, + state.dataMstBal->TempOutsideAirFD(SurfNum), + 1.0, + state.dataEnvrn->OutBaroPress, + RoutineNameExtEnvDrySurf)) + + state.dataMstBal->RhoVaporAirOut(SurfNum)) * + PsyCpAirFnW(state.dataEnvrn->OutHumRat)); + // check for saturation conditions of air + // Local temporary saturated vapor density for checking + Real64 RhoVaporSat = PsyRhovFnTdbRh(state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, HBSurfManDrySurfCondFD); + if (state.dataMstBal->RhoVaporAirOut(SurfNum) > RhoVaporSat) state.dataMstBal->RhoVaporAirOut(SurfNum) = RhoVaporSat; + state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum); + state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum); + state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum); + } } - } else { // Surface is dry, use the normal correlation + } else { // No wind + + // Calculate exterior heat transfer coefficients for windspeed = 0 + InitExteriorConvectionCoeff(state, + SurfNum, + HMovInsul, + RoughSurf, + AbsThermSurf, + state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum), + state.dataHeatBalSurf->SurfHcExt(SurfNum), + state.dataHeatBalSurf->SurfHSkyExt(SurfNum), + state.dataHeatBalSurf->SurfHGrdExt(SurfNum), + state.dataHeatBalSurf->SurfHAirExt(SurfNum)); TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum); @@ -7195,22 +7330,46 @@ void CalcHeatBalanceOutsideSurf(EnergyPlusData &state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, state.dataEnvrn->OutBaroPress, - RoutineNameExtEnvDrySurf)) + + RoutineNameNoWind)) + state.dataMstBal->RhoVaporAirOut(SurfNum)) * PsyCpAirFnW(state.dataEnvrn->OutHumRat)); - // check for saturation conditions of air - // Local temporary saturated vapor density for checking - Real64 RhoVaporSat = PsyRhovFnTdbRh(state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, HBSurfManDrySurfCondFD); - if (state.dataMstBal->RhoVaporAirOut(SurfNum) > RhoVaporSat) state.dataMstBal->RhoVaporAirOut(SurfNum) = RhoVaporSat; state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum); state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum); state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum); } } + // Calculate LWR from surrounding surfaces if defined for an exterior surface + if (state.dataSurface->Surface(SurfNum).SurfHasSurroundingSurfProperty) { + int SrdSurfsNum = state.dataSurface->Surface(SurfNum).SurfSurroundingSurfacesNum; + // Absolute temperature of the outside surface of an exterior surface + Real64 TSurf = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) + DataGlobalConstants::KelvinConv; + for (int SrdSurfNum = 1; SrdSurfNum <= state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).TotSurroundingSurface; + SrdSurfNum++) { + // View factor of a surrounding surface + Real64 SrdSurfViewFac = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SurroundingSurfs(SrdSurfNum).ViewFactor; + // Absolute temperature of a surrounding surface + Real64 SrdSurfTempAbs = + GetCurrentScheduleValue( + state, state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SurroundingSurfs(SrdSurfNum).TempSchNum) + + DataGlobalConstants::KelvinConv; + state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs(SurfNum) += + DataGlobalConstants::StefanBoltzmann * AbsThermSurf * SrdSurfViewFac * (pow_4(SrdSurfTempAbs) - pow_4(TSurf)); + } + } - } else { // No wind + if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF || + Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD || + Surface(SurfNum).Class == SurfaceClass::TDD_Dome) { + CalcOutsideSurfTemp(state, SurfNum, zoneNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag); + if (MovInsulErrorFlag) ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions."); + } + } break; + case KivaFoundation: { + DataSurfaces::SurfaceRoughness RoughSurf = + state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).Roughness; + Real64 AbsThermSurf = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).AbsorpThermal; - // Calculate exterior heat transfer coefficients for windspeed = 0 + // Set Kiva exterior convection algorithms InitExteriorConvectionCoeff(state, SurfNum, HMovInsul, @@ -7221,136 +7380,71 @@ void CalcHeatBalanceOutsideSurf(EnergyPlusData &state, state.dataHeatBalSurf->SurfHSkyExt(SurfNum), state.dataHeatBalSurf->SurfHGrdExt(SurfNum), state.dataHeatBalSurf->SurfHAirExt(SurfNum)); + } break; + default: { // for interior or other zone surfaces - TempExt = state.dataSurface->SurfOutDryBulbTemp(SurfNum); + if (Surface(SurfNum).ExtBoundCond == SurfNum) { // Regular partition/internal mass - if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD || - Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { - // Set variables used in the FD moisture balance and HAMT - state.dataMstBal->TempOutsideAirFD(SurfNum) = TempExt; - state.dataMstBal->RhoVaporAirOut(SurfNum) = - PsyRhovFnTdbWPb(state.dataMstBal->TempOutsideAirFD(SurfNum), state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress); - state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHcExt(SurfNum); - state.dataMstBal->HMassConvExtFD(SurfNum) = - state.dataMstBal->HConvExtFD(SurfNum) / - ((PsyRhoAirFnPbTdbW( - state, - state.dataEnvrn->OutBaroPress, - state.dataMstBal->TempOutsideAirFD(SurfNum), - PsyWFnTdbRhPb( - state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, state.dataEnvrn->OutBaroPress, RoutineNameNoWind)) + - state.dataMstBal->RhoVaporAirOut(SurfNum)) * - PsyCpAirFnW(state.dataEnvrn->OutHumRat)); - state.dataMstBal->HSkyFD(SurfNum) = state.dataHeatBalSurf->SurfHSkyExt(SurfNum); - state.dataMstBal->HGrndFD(SurfNum) = state.dataHeatBalSurf->SurfHGrdExt(SurfNum); - state.dataMstBal->HAirFD(SurfNum) = state.dataHeatBalSurf->SurfHAirExt(SurfNum); - } - } - // Calculate LWR from surrounding surfaces if defined for an exterior surface - if (state.dataSurface->Surface(SurfNum).SurfHasSurroundingSurfProperty) { - int SrdSurfsNum = state.dataSurface->Surface(SurfNum).SurfSurroundingSurfacesNum; - // Absolute temperature of the outside surface of an exterior surface - Real64 TSurf = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) + DataGlobalConstants::KelvinConv; - for (int SrdSurfNum = 1; SrdSurfNum <= state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).TotSurroundingSurface; - SrdSurfNum++) { - // View factor of a surrounding surface - Real64 SrdSurfViewFac = state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SurroundingSurfs(SrdSurfNum).ViewFactor; - // Absolute temperature of a surrounding surface - Real64 SrdSurfTempAbs = - GetCurrentScheduleValue( - state, state.dataSurface->SurroundingSurfsProperty(SrdSurfsNum).SurroundingSurfs(SrdSurfNum).TempSchNum) + - DataGlobalConstants::KelvinConv; - state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs(SurfNum) += - DataGlobalConstants::StefanBoltzmann * AbsThermSurf * SrdSurfViewFac * (pow_4(SrdSurfTempAbs) - pow_4(TSurf)); - } - } - - if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CTF || - Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD || - Surface(SurfNum).Class == SurfaceClass::TDD_Dome) { - CalcOutsideSurfTemp(state, SurfNum, zoneNum, ConstrNum, HMovInsul, TempExt, MovInsulErrorFlag); - if (MovInsulErrorFlag) ShowFatalError(state, "CalcOutsideSurfTemp: Program terminates due to preceding conditions."); - } - } break; - case KivaFoundation: { - DataSurfaces::SurfaceRoughness RoughSurf = - state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).Roughness; - Real64 AbsThermSurf = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).AbsorpThermal; - - // Set Kiva exterior convection algorithms - InitExteriorConvectionCoeff(state, - SurfNum, - HMovInsul, - RoughSurf, - AbsThermSurf, - state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum), - state.dataHeatBalSurf->SurfHcExt(SurfNum), - state.dataHeatBalSurf->SurfHSkyExt(SurfNum), - state.dataHeatBalSurf->SurfHGrdExt(SurfNum), - state.dataHeatBalSurf->SurfHAirExt(SurfNum)); - } break; - default: { // for interior or other zone surfaces + state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum); - if (Surface(SurfNum).ExtBoundCond == SurfNum) { // Regular partition/internal mass + // No need to set any radiant system heat balance coefficients here--will be done during inside heat balance - state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum); - - // No need to set any radiant system heat balance coefficients here--will be done during inside heat balance - - if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD || - Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { - // Set variables used in the FD moisture balance HAMT - state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum); - state.dataMstBal->RhoVaporAirOut(SurfNum) = state.dataMstBal->RhoVaporAirIn(SurfNum); - state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum); - state.dataMstBal->HMassConvExtFD(SurfNum) = - state.dataMstBal->HConvExtFD(SurfNum) / - ((PsyRhoAirFnPbTdbW( - state, - state.dataEnvrn->OutBaroPress, - state.dataMstBal->TempOutsideAirFD(SurfNum), - PsyWFnTdbRhPb( - state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, state.dataEnvrn->OutBaroPress, RoutineNameOther)) + - state.dataMstBal->RhoVaporAirOut(SurfNum)) * - PsyCpAirFnW(state.dataEnvrn->OutHumRat)); - state.dataMstBal->HSkyFD(SurfNum) = 0.0; - state.dataMstBal->HGrndFD(SurfNum) = 0.0; - state.dataMstBal->HAirFD(SurfNum) = 0.0; - } + if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD || + Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { + // Set variables used in the FD moisture balance HAMT + state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfTempIn(SurfNum); + state.dataMstBal->RhoVaporAirOut(SurfNum) = state.dataMstBal->RhoVaporAirIn(SurfNum); + state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum); + state.dataMstBal->HMassConvExtFD(SurfNum) = + state.dataMstBal->HConvExtFD(SurfNum) / + ((PsyRhoAirFnPbTdbW( + state, + state.dataEnvrn->OutBaroPress, + state.dataMstBal->TempOutsideAirFD(SurfNum), + PsyWFnTdbRhPb( + state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, state.dataEnvrn->OutBaroPress, RoutineNameOther)) + + state.dataMstBal->RhoVaporAirOut(SurfNum)) * + PsyCpAirFnW(state.dataEnvrn->OutHumRat)); + state.dataMstBal->HSkyFD(SurfNum) = 0.0; + state.dataMstBal->HGrndFD(SurfNum) = 0.0; + state.dataMstBal->HAirFD(SurfNum) = 0.0; + } - } else { // Interzone partition + } else { // Interzone partition - state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) = - state.dataHeatBalSurf->SurfInsideTempHist(1)(Surface(SurfNum).ExtBoundCond); + state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum) = + state.dataHeatBalSurf->SurfInsideTempHist(1)(Surface(SurfNum).ExtBoundCond); - // No need to set any radiant system heat balance coefficients here--will be done during inside heat balance + // No need to set any radiant system heat balance coefficients here--will be done during inside heat balance - if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD || - Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { - // Set variables used in the FD moisture balance and HAMT - state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHist(1)(Surface(SurfNum).ExtBoundCond); - state.dataMstBal->RhoVaporAirOut(SurfNum) = state.dataMstBal->RhoVaporAirIn(Surface(SurfNum).ExtBoundCond); - state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(Surface(SurfNum).ExtBoundCond); - state.dataMstBal->HMassConvExtFD(SurfNum) = - state.dataMstBal->HConvExtFD(SurfNum) / - ((PsyRhoAirFnPbTdbW( - state, - state.dataEnvrn->OutBaroPress, - state.dataMstBal->TempOutsideAirFD(SurfNum), - PsyWFnTdbRhPb( - state, state.dataMstBal->TempOutsideAirFD(SurfNum), 1.0, state.dataEnvrn->OutBaroPress, RoutineNameIZPart)) + - state.dataMstBal->RhoVaporAirOut(SurfNum)) * - PsyCpAirFnW(state.dataEnvrn->OutHumRat)); - state.dataMstBal->HSkyFD(SurfNum) = 0.0; - state.dataMstBal->HGrndFD(SurfNum) = 0.0; - state.dataMstBal->HAirFD(SurfNum) = 0.0; + if (Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD || + Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { + // Set variables used in the FD moisture balance and HAMT + state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalSurf->SurfInsideTempHist(1)(Surface(SurfNum).ExtBoundCond); + state.dataMstBal->RhoVaporAirOut(SurfNum) = state.dataMstBal->RhoVaporAirIn(Surface(SurfNum).ExtBoundCond); + state.dataMstBal->HConvExtFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(Surface(SurfNum).ExtBoundCond); + state.dataMstBal->HMassConvExtFD(SurfNum) = + state.dataMstBal->HConvExtFD(SurfNum) / ((PsyRhoAirFnPbTdbW(state, + state.dataEnvrn->OutBaroPress, + state.dataMstBal->TempOutsideAirFD(SurfNum), + PsyWFnTdbRhPb(state, + state.dataMstBal->TempOutsideAirFD(SurfNum), + 1.0, + state.dataEnvrn->OutBaroPress, + RoutineNameIZPart)) + + state.dataMstBal->RhoVaporAirOut(SurfNum)) * + PsyCpAirFnW(state.dataEnvrn->OutHumRat)); + state.dataMstBal->HSkyFD(SurfNum) = 0.0; + state.dataMstBal->HGrndFD(SurfNum) = 0.0; + state.dataMstBal->HAirFD(SurfNum) = 0.0; + } } + // This ends the calculations for this surface and goes on to the next SurfNum + } break; } - // This ends the calculations for this surface and goes on to the next SurfNum - } break; - } - state.dataHeatBalSurf->SurfQdotConvOutPerArea(SurfNum) = GetQdotConvOutPerArea(state, SurfNum); + state.dataHeatBalSurf->SurfQdotConvOutPerArea(SurfNum) = GetQdotConvOutPerArea(state, SurfNum); + } } } // ...end of DO loop over all surface (actually heat transfer surfaces) } @@ -7392,13 +7486,15 @@ void CalcHeatBalanceInsideSurf(EnergyPlusData &state, // Precompute whether CTF temperature limits will be needed state.dataHeatBalSurf->Zone_has_mixed_HT_models.resize(state.dataGlobal->NumOfZones + 1, false); for (int iZone = 1; iZone <= state.dataGlobal->NumOfZones; ++iZone) { - auto const &zone(state.dataHeatBal->Zone(iZone)); - for (int iSurf = zone.HTSurfaceFirst, eSurf = zone.HTSurfaceLast; iSurf <= eSurf; ++iSurf) { - auto const alg(Surface(iSurf).HeatTransferAlgorithm); - if ((alg == DataSurfaces::HeatTransferModel::CondFD) || (alg == DataSurfaces::HeatTransferModel::HAMT) || - (alg == DataSurfaces::HeatTransferModel::Kiva)) { - state.dataHeatBalSurf->Zone_has_mixed_HT_models[iZone] = true; - break; + for (int spaceNum : state.dataHeatBal->Zone(iZone).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int iSurf = thisSpace.HTSurfaceFirst, eSurf = thisSpace.HTSurfaceLast; iSurf <= eSurf; ++iSurf) { + auto const alg(Surface(iSurf).HeatTransferAlgorithm); + if ((alg == DataSurfaces::HeatTransferModel::CondFD) || (alg == DataSurfaces::HeatTransferModel::HAMT) || + (alg == DataSurfaces::HeatTransferModel::Kiva)) { + state.dataHeatBalSurf->Zone_has_mixed_HT_models[iZone] = true; + break; + } } } } @@ -7593,8 +7689,8 @@ void CalcHeatBalanceInsideSurf2(EnergyPlusData &state, if ((surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) || (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT)) { int ZoneNum = Surface(SurfNum).Zone; - Real64 const MAT_zone(state.dataHeatBalFanSys->MAT(ZoneNum)); - Real64 const ZoneAirHumRat_zone(max(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum), 1.0e-5)); + Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT); + Real64 const ZoneAirHumRat_zone(max(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZoneAirHumRat, 1.0e-5)); Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum)); state.dataMstBal->RhoVaporAirIn(SurfNum) = @@ -7631,7 +7727,7 @@ void CalcHeatBalanceInsideSurf2(EnergyPlusData &state, Real64 &TH11(state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfNum)); int const ConstrNum = surface.Construction; auto const &construct(state.dataConstruction->Construct(ConstrNum)); - Real64 const MAT_zone(state.dataHeatBalFanSys->MAT(ZoneNum)); + Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT); Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(SurfNum) = state.dataHeatBalSurf->SurfHConvInt(SurfNum)); if (surface.ExtBoundCond == SurfNum) { @@ -7870,7 +7966,8 @@ void CalcHeatBalanceInsideSurf2(EnergyPlusData &state, int OtherSideSurfNum = surface.ExtBoundCond; // ZoneNum = surface.Zone; OtherSideZoneNum = Surface(OtherSideSurfNum).Zone; - state.dataMstBal->TempOutsideAirFD(SurfNum) = state.dataHeatBalFanSys->MAT(OtherSideZoneNum); + state.dataMstBal->TempOutsideAirFD(SurfNum) = + state.dataZoneTempPredictorCorrector->zoneHeatBalance(OtherSideZoneNum).MAT; } HeatBalanceHAMTManager::ManageHeatBalHAMT(state, SurfNum, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), TempSurfOutTmp); } @@ -8197,24 +8294,26 @@ void CalcHeatBalanceInsideSurf2(EnergyPlusData &state, // Update SumHmXXXX for non-window EMPD or HAMT surfaces if (state.dataHeatBal->AnyEMPD || state.dataHeatBal->AnyHAMT) { - // these SumHmA* variables are only used for EMPD and HAMT and should be reset each time step - state.dataHeatBalFanSys->SumHmAW = 0.0; - state.dataHeatBalFanSys->SumHmARa = 0.0; - state.dataHeatBalFanSys->SumHmARaW = 0.0; + // these SumHmA* variables are only used for EMPD and HAMT and should be reset each time step (and every iteration) + for (auto &thisZoneHB : state.dataZoneTempPredictorCorrector->zoneHeatBalance) { + thisZoneHB.SumHmAW = 0.0; + thisZoneHB.SumHmARa = 0.0; + thisZoneHB.SumHmARaW = 0.0; + } for (int SurfNum : HTNonWindowSurfs) { auto const &surface(Surface(SurfNum)); int ZoneNum = surface.Zone; + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { HeatBalanceHAMTManager::UpdateHeatBalHAMT(state, SurfNum); Real64 const FD_Area_fac(state.dataMstBal->HMassConvInFD(SurfNum) * surface.Area); - state.dataHeatBalFanSys->SumHmAW(ZoneNum) += - FD_Area_fac * (state.dataMstBal->RhoVaporSurfIn(SurfNum) - state.dataMstBal->RhoVaporAirIn(SurfNum)); + thisZoneHB.SumHmAW += FD_Area_fac * (state.dataMstBal->RhoVaporSurfIn(SurfNum) - state.dataMstBal->RhoVaporAirIn(SurfNum)); - Real64 const MAT_zone(state.dataHeatBalFanSys->MAT(surface.Zone)); + Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(surface.Zone).MAT); RhoAirZone = Psychrometrics::PsyRhoAirFnPbTdbW( state, state.dataEnvrn->OutBaroPress, @@ -8232,10 +8331,9 @@ void CalcHeatBalanceInsideSurf2(EnergyPlusData &state, Psychrometrics::PsyRhFnTdbRhov(state, surfInTemp, state.dataMstBal->RhoVaporSurfIn(SurfNum), wsurf), state.dataEnvrn->OutBaroPress); - state.dataHeatBalFanSys->SumHmARa(ZoneNum) += FD_Area_fac * RhoAirZone; + thisZoneHB.SumHmARa += FD_Area_fac * RhoAirZone; - state.dataHeatBalFanSys->SumHmARaW(ZoneNum) += - FD_Area_fac * state.dataMstBal->RhoVaporSurfIn(SurfNum); // old eq'n: FD_Area_fac * RhoAirZone * Wsurf; + thisZoneHB.SumHmARaW += FD_Area_fac * state.dataMstBal->RhoVaporSurfIn(SurfNum); // old eq'n: FD_Area_fac * RhoAirZone * Wsurf; } else if (surface.HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) { // need to calculate the amount of moisture that is entering or @@ -8249,10 +8347,9 @@ void CalcHeatBalanceInsideSurf2(EnergyPlusData &state, MoistureBalanceEMPDManager::UpdateMoistureBalanceEMPD(state, SurfNum); state.dataMstBal->RhoVaporSurfIn(SurfNum) = state.dataMstBalEMPD->RVSurface(SurfNum); Real64 const FD_Area_fac(state.dataMstBal->HMassConvInFD(SurfNum) * surface.Area); - state.dataHeatBalFanSys->SumHmAW(ZoneNum) += - FD_Area_fac * (state.dataMstBal->RhoVaporSurfIn(SurfNum) - state.dataMstBal->RhoVaporAirIn(SurfNum)); - Real64 const MAT_zone(state.dataHeatBalFanSys->MAT(ZoneNum)); - state.dataHeatBalFanSys->SumHmARa(ZoneNum) += + thisZoneHB.SumHmAW += FD_Area_fac * (state.dataMstBal->RhoVaporSurfIn(SurfNum) - state.dataMstBal->RhoVaporAirIn(SurfNum)); + Real64 const MAT_zone(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT); + thisZoneHB.SumHmARa += FD_Area_fac * Psychrometrics::PsyRhoAirFnPbTdbW( state, @@ -8263,7 +8360,7 @@ void CalcHeatBalanceInsideSurf2(EnergyPlusData &state, Psychrometrics::PsyRhFnTdbRhovLBnd0C(state, MAT_zone, state.dataMstBal->RhoVaporAirIn(SurfNum)), state.dataEnvrn->OutBaroPress)); // surfInTemp, PsyWFnTdbRhPb( surfInTemp, PsyRhFnTdbRhovLBnd0C( // surfInTemp, RhoVaporAirIn( SurfNum ) ), OutBaroPress ) ); - state.dataHeatBalFanSys->SumHmARaW(ZoneNum) += FD_Area_fac * state.dataMstBal->RhoVaporSurfIn(SurfNum); + thisZoneHB.SumHmARaW += FD_Area_fac * state.dataMstBal->RhoVaporSurfIn(SurfNum); } } } @@ -8289,20 +8386,23 @@ void CalcHeatBalanceInsideSurf2CTFOnly(EnergyPlusData &state, if (state.dataHeatBalSurfMgr->calcHeatBalInsideSurfCTFOnlyFirstTime) { // Set up coefficient arrays that never change - loop over non-window HT surfaces for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) { - int const firstSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceFirst; - int const lastSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceLast; - for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - int const ConstrNum = Surface(surfNum).Construction; - auto const &construct(state.dataConstruction->Construct(ConstrNum)); - if (Surface(surfNum).ExtBoundCond == surfNum) { - state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) = 1; - } else { - state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) = 0; - } - if (construct.SourceSinkPresent) { - state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) = 1; - } else { - state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) = 0; + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst; + int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast; + for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { + int const ConstrNum = Surface(surfNum).Construction; + auto const &construct(state.dataConstruction->Construct(ConstrNum)); + if (Surface(surfNum).ExtBoundCond == surfNum) { + state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) = 1; + } else { + state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) = 0; + } + if (construct.SourceSinkPresent) { + state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) = 1; + } else { + state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) = 0; + } } } } @@ -8311,99 +8411,103 @@ void CalcHeatBalanceInsideSurf2CTFOnly(EnergyPlusData &state, } for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) { - // loop over all heat transfer surface except TDD Dome. - int const firstSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrWinSurfaceFirst; - int const lastSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrWinSurfaceLast; - // determine reference air temperatures and other variable terms - loop over all surfaces - for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - auto &surface(Surface(surfNum)); - if (state.dataSurface->UseRepresentativeSurfaceCalculations) { - int repSurfNum = surface.RepresentativeCalcSurfNum; - if (surfNum != repSurfNum) continue; - } + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + // loop over all heat transfer surface except TDD Dome. + int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst; + int const lastSurf = thisSpace.OpaqOrWinSurfaceLast; + // determine reference air temperatures and other variable terms - loop over all surfaces + for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { + auto &surface(Surface(surfNum)); + if (state.dataSurface->UseRepresentativeSurfaceCalculations) { + int repSurfNum = surface.RepresentativeCalcSurfNum; + if (surfNum != repSurfNum) continue; + } - int const ConstrNum = Surface(surfNum).Construction; - auto const &construct(state.dataConstruction->Construct(ConstrNum)); - state.dataHeatBalSurf->SurfCTFCross0(surfNum) = construct.CTFCross(0); - state.dataHeatBalSurf->SurfCTFInside0(surfNum) = construct.CTFInside(0); - state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) = construct.CTFSourceIn(0); - state.dataHeatBalSurf->SurfTempOutHist(surfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum); - if (construct.SourceSinkPresent) { - state.dataHeatBalSurf->SurfQSourceSinkHist(surfNum) = state.dataHeatBalSurf->SurfQsrcHist(surfNum, 1); - } + int const ConstrNum = Surface(surfNum).Construction; + auto const &construct(state.dataConstruction->Construct(ConstrNum)); + state.dataHeatBalSurf->SurfCTFCross0(surfNum) = construct.CTFCross(0); + state.dataHeatBalSurf->SurfCTFInside0(surfNum) = construct.CTFInside(0); + state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) = construct.CTFSourceIn(0); + state.dataHeatBalSurf->SurfTempOutHist(surfNum) = state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum); + if (construct.SourceSinkPresent) { + state.dataHeatBalSurf->SurfQSourceSinkHist(surfNum) = state.dataHeatBalSurf->SurfQsrcHist(surfNum, 1); + } - if (state.dataHeatBalSurf->AnyRadiantSystems(surfNum)) - state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) = GetSurfQdotRadHVACInPerArea(state, surfNum); - // The special heat balance terms for pools are used only when the pool is operating, so IsPool can change - if (state.dataSurface->SurfIsPool(surfNum)) { - if ((std::abs(state.dataHeatBalFanSys->QPoolSurfNumerator(surfNum)) >= PoolIsOperatingLimit) || - (std::abs(state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum)) >= PoolIsOperatingLimit)) { - state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) = 1; - } else { - state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) = 0; + if (state.dataHeatBalSurf->AnyRadiantSystems(surfNum)) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) = GetSurfQdotRadHVACInPerArea(state, surfNum); + // The special heat balance terms for pools are used only when the pool is operating, so IsPool can change + if (state.dataSurface->SurfIsPool(surfNum)) { + if ((std::abs(state.dataHeatBalFanSys->QPoolSurfNumerator(surfNum)) >= PoolIsOperatingLimit) || + (std::abs(state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum)) >= PoolIsOperatingLimit)) { + state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) = 1; + } else { + state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) = 0; + } } + Real64 RefAirTemp = state.dataSurface->Surface(surfNum).getInsideAirTemperature(state, surfNum); + state.dataHeatBalSurfMgr->RefAirTemp(surfNum) = RefAirTemp; + state.dataHeatBal->SurfTempEffBulkAir(surfNum) = state.dataHeatBalSurfMgr->RefAirTemp(surfNum); } - Real64 RefAirTemp = state.dataSurface->Surface(surfNum).getInsideAirTemperature(state, surfNum); - state.dataHeatBalSurfMgr->RefAirTemp(surfNum) = RefAirTemp; - state.dataHeatBal->SurfTempEffBulkAir(surfNum) = state.dataHeatBalSurfMgr->RefAirTemp(surfNum); - } - - // Following variables must be reset due to possible recall of this routine by radiant and Resimulate routines. - // CalcWindowHeatBalance is called, then, multiple times and these need to be initialized before each call to - // CalcWindowHeatBalance. - // Only for Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window - int const firstWindowSurf = state.dataHeatBal->Zone(zoneNum).WindowSurfaceFirst; - int const lastWindowSurf = state.dataHeatBal->Zone(zoneNum).WindowSurfaceLast; - for (int surfNum = firstWindowSurf; surfNum <= lastWindowSurf; ++surfNum) { - state.dataSurface->SurfWinHeatGain(surfNum) = 0.0; - state.dataSurface->SurfWinHeatGainRep(surfNum) = 0.0; - state.dataSurface->SurfWinHeatLossRep(surfNum) = 0.0; - state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) = 0.0; - state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = 0.0; - state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) = 0.0; - state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = 0.0; - state.dataSurface->SurfWinGainConvShadeToZoneRep(surfNum) = 0.0; - state.dataSurface->SurfWinGainIRShadeToZoneRep(surfNum) = 0.0; - state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = 0.0; - state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = 0.0; - state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = 0.0; - state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = 0.0; - } - - // Calculate heat extract due to additional heat flux source term as the surface boundary condition - all HT surfaces - if (state.dataSurface->AnyHeatBalanceInsideSourceTerm) { - for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - if (Surface(surfNum).InsideHeatSourceTermSchedule) { - state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) = - EnergyPlus::ScheduleManager::GetCurrentScheduleValue(state, Surface(surfNum).InsideHeatSourceTermSchedule); + + // Following variables must be reset due to possible recall of this routine by radiant and Resimulate routines. + // CalcWindowHeatBalance is called, then, multiple times and these need to be initialized before each call to + // CalcWindowHeatBalance. + // Only for Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window + int const firstWindowSurf = thisSpace.WindowSurfaceFirst; + int const lastWindowSurf = thisSpace.WindowSurfaceLast; + for (int surfNum = firstWindowSurf; surfNum <= lastWindowSurf; ++surfNum) { + state.dataSurface->SurfWinHeatGain(surfNum) = 0.0; + state.dataSurface->SurfWinHeatGainRep(surfNum) = 0.0; + state.dataSurface->SurfWinHeatLossRep(surfNum) = 0.0; + state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) = 0.0; + state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = 0.0; + state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) = 0.0; + state.dataSurface->SurfWinGainFrameDividerToZoneRep(surfNum) = 0.0; + state.dataSurface->SurfWinGainConvShadeToZoneRep(surfNum) = 0.0; + state.dataSurface->SurfWinGainIRShadeToZoneRep(surfNum) = 0.0; + state.dataSurface->SurfWinFrameQRadOutAbs(surfNum) = 0.0; + state.dataSurface->SurfWinFrameQRadInAbs(surfNum) = 0.0; + state.dataSurface->SurfWinDividerQRadOutAbs(surfNum) = 0.0; + state.dataSurface->SurfWinDividerQRadInAbs(surfNum) = 0.0; + } + + // Calculate heat extract due to additional heat flux source term as the surface boundary condition - all HT surfaces + if (state.dataSurface->AnyHeatBalanceInsideSourceTerm) { + for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { + if (Surface(surfNum).InsideHeatSourceTermSchedule) { + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) = + EnergyPlus::ScheduleManager::GetCurrentScheduleValue(state, Surface(surfNum).InsideHeatSourceTermSchedule); + } } } - } - // Set up coefficient arrays prior to calculations and precalc terms that do no change during iteration - non-window surfaces - int const firstNonWinSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceFirst; - int const lastNonWinSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceLast; - Real64 const timeStepZoneSeconds = state.dataGlobal->TimeStepZoneSec; // local for vectorization - Real64 const iterDampConstant = IterDampConst; // local for vectorization - // this loop auto-vectorizes - for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) { - auto &surface(Surface(surfNum)); - if (state.dataSurface->UseRepresentativeSurfaceCalculations) { - int repSurfNum = surface.RepresentativeCalcSurfNum; - if (surfNum != repSurfNum) continue; - } + // Set up coefficient arrays prior to calculations and precalc terms that do no change during iteration - non-window surfaces + int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst; + int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast; + Real64 const timeStepZoneSeconds = state.dataGlobal->TimeStepZoneSec; // local for vectorization + Real64 const iterDampConstant = IterDampConst; // local for vectorization + // this loop auto-vectorizes + for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) { + auto &surface(Surface(surfNum)); + if (state.dataSurface->UseRepresentativeSurfaceCalculations) { + int repSurfNum = surface.RepresentativeCalcSurfNum; + if (surfNum != repSurfNum) continue; + } - // Pre-calculate a few terms before the iteration loop - state.dataHeatBalSurf->SurfTempTerm(surfNum) = - state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) + - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) + - state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) + - state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) + (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / timeStepZoneSeconds); - state.dataHeatBalSurf->SurfTempDiv(surfNum) = - 1.0 / (state.dataHeatBalSurf->SurfCTFInside0(surfNum) - - state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) + - state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum) + - (!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) * state.dataHeatBalSurf->SurfHConvInt(surfNum) + iterDampConstant); + // Pre-calculate a few terms before the iteration loop + state.dataHeatBalSurf->SurfTempTerm(surfNum) = + state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) + + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) + + state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) + + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) + + (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / timeStepZoneSeconds); + state.dataHeatBalSurf->SurfTempDiv(surfNum) = + 1.0 / (state.dataHeatBalSurf->SurfCTFInside0(surfNum) - + state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) + + state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum) + + (!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) * state.dataHeatBalSurf->SurfHConvInt(surfNum) + iterDampConstant); + } } } @@ -8430,352 +8534,372 @@ void CalcHeatBalanceInsideSurf2CTFOnly(EnergyPlusData &state, ConvectionCoefficients::InitInteriorConvectionCoeffs(state, state.dataHeatBalSurf->SurfTempIn, ZoneToResimulate); // Since HConvIn has changed re-calculate a few terms - non-window surfaces for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) { - int const firstSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceFirst; - int const lastSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceLast; + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst; + int const lastSurf = thisSpace.OpaqOrIntMassSurfaceLast; + + Real64 const timeStepZoneSeconds = state.dataGlobal->TimeStepZoneSec; // local for vectorization + Real64 const iterDampConstant = IterDampConst; // local for vectorization + // this loop auto-vectorizes + for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { + auto &surface(Surface(surfNum)); + if (state.dataSurface->UseRepresentativeSurfaceCalculations) { + int repSurfNum = surface.RepresentativeCalcSurfNum; + if (surfNum != repSurfNum) continue; + } - Real64 const timeStepZoneSeconds = state.dataGlobal->TimeStepZoneSec; // local for vectorization - Real64 const iterDampConstant = IterDampConst; // local for vectorization - // this loop auto-vectorizes - for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - auto &surface(Surface(surfNum)); - if (state.dataSurface->UseRepresentativeSurfaceCalculations) { - int repSurfNum = surface.RepresentativeCalcSurfNum; - if (surfNum != repSurfNum) continue; + state.dataHeatBalSurf->SurfTempTerm(surfNum) = + state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) + + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) + + state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) + + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) + + (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / timeStepZoneSeconds); + state.dataHeatBalSurf->SurfTempDiv(surfNum) = + 1.0 / (state.dataHeatBalSurf->SurfCTFInside0(surfNum) - + state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) + + state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum) + + (!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) * state.dataHeatBalSurf->SurfHConvInt(surfNum) + + iterDampConstant); } - - state.dataHeatBalSurf->SurfTempTerm(surfNum) = - state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) + - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) + - state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) + - state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) + - (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / timeStepZoneSeconds); - state.dataHeatBalSurf->SurfTempDiv(surfNum) = - 1.0 / - (state.dataHeatBalSurf->SurfCTFInside0(surfNum) - - state.dataHeatBalSurf->SurfIsAdiabatic(surfNum) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) + - state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->PoolHeatTransCoefs(surfNum) + - (!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) * state.dataHeatBalSurf->SurfHConvInt(surfNum) + iterDampConstant); } } } // Loop over non-window surfaces for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) { - int const firstNonWinSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceFirst; - int const lastNonWinSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceLast; - Real64 const iterDampConstant = IterDampConst; // local for vectorization - // this loop auto-vectorizes - for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) { - // Perform heat balance on the inside face of the surface ... - // The following are possibilities here (this function only does CTF, see CalcHeatBalanceInsideSurf2 for others): - // (a) the surface is a pool (no movable insulation, no source/sink, only CTF solution algorithm) - // (b) the surface is adiabatic (a partition), in which case the temperature of both sides are the same - // (c) standard (or interzone) opaque surface with no movable insulation, normal heat balance equation - // (d) standard (or interzone) window: call to CalcWindowHeatBalance to get window layer temperatures - // (e) standard opaque surface with movable insulation, special two-part equation - // In the surface calculation there are the following Algorithm types for opaque surfaces that - // do not have movable insulation: - // (a) the regular CTF calc (SolutionAlgo = UseCTF) - // (b) the EMPD calc (Solutionalgo = UseEMPD) - // (c) the CondFD calc (SolutionAlgo = UseCondFD) - // (d) the HAMT calc (solutionalgo = UseHAMT). - - // For adiabatic surface: - // Adiabatic: TempDiv = (1.0 / (construct.CTFInside(0) - construct.CTFCross(0) + HConvIn_surf + IterDampConst)); - // Adiabatic: SurfTempInTmp(SurfNum) = (TempTerm + IterDampConst * SurfTempInsOld(SurfNum)) * TempDiv; - // Ad+Source: SurfTempInTmp(SurfNum) = (TempTerm + construct.CTFSourceIn(0) * SurfQsrcHist(SurfNum, 1) + IterDampConst * - // SurfTempInsOld(SurfNum)) * TempDiv; Ad+Pool: TempDiv = (1.0 / (construct.CTFInside(0) - construct.CTFCross(0) + - // PoolHeatTransCoefs(SurfNum) + IterDampConst); Ad+Pool: SurfTempInTmp(SurfNum) = (SurfCTFConstInPart(SurfNum) + - // QPoolSurfNumerator(SurfNum) + IterDampConst * SurfTempInsOld(SurfNum)) * TempDiv; - - // For standard or interzone surface: - // Standard: TempDiv = (1.0 / (construct.CTFInside(0) + HConvIn_surf + IterDampConst)); - // Standard: SurfTempInTmp(SurfNum) = (TempTerm + IterDampConst * SurfTempInsOld(SurfNum) + construct.CTFCross(0) * TH11) * - // TempDiv; Std+Source: SurfTempInTmp(SurfNum) = (TempTerm + construct.CTFSourceIn(0) * SurfQsrcHist(SurfNum, 1) + IterDampConst * - // SurfTempInsOld(SurfNum)) * TempDiv; Std+Pool: TempDiv = (1.0 / (construct.CTFInside(0) + PoolHeatTransCoefs(SurfNum) + - // IterDampConst); Std+Pool: SurfTempInTmp(SurfNum) = (SurfCTFConstInPart(SurfNum) + QPoolSurfNumerator(SurfNum) + IterDampConst* - // SurfTempInsOld(SurfNum) + construct.CTFCross(0) * TH11) * TempDiv; - - // Composite with Adiabatic/Source/Pool flags: - // TempDiv = (1.0 / (construct.CTFInside(0) - SurfIsAdiabatic*construct.CTFCross(0)+ - // SurfIsOperatingPool*PoolHeatTransCoefs(SurfNum) + IsNotPoolSurf*HConvIn_surf + IterDampConst)); SurfTempInTmp(SurfNum) - // = (IsNotPoolSurf*TempTerm + IsSource*construct.CTFSourceIn(0) * SurfQsrcHist(SurfNum, 1) + - // SurfIsOperatingPool*SurfCTFConstInPart(SurfNum) + SurfIsOperatingPool*QPoolSurfNumerator(SurfNum) - // + IterDampConst * SurfTempInsOld(SurfNum)+ IsNotAdiabatic*IsNotSource*construct.CTFCross(0) - // * TH11) * TempDiv; - - // Calculate the current inside surface temperature - state.dataHeatBalSurf->SurfTempInTmp(surfNum) = - ((!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) * - (state.dataHeatBalSurf->SurfTempTerm(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum)) + - state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) * state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) * - state.dataHeatBalSurf->SurfQSourceSinkHist(surfNum) + - state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + - state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->QPoolSurfNumerator(surfNum) + - iterDampConstant * state.dataHeatBalSurf->SurfTempInsOld(surfNum) + - (!state.dataHeatBalSurf->SurfIsAdiabatic(surfNum)) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) * - state.dataHeatBalSurf->SurfTempOutHist(surfNum)) * - state.dataHeatBalSurf->SurfTempDiv(surfNum); - // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW - // radiation from internal sources | Convection from surface to zone air | Net radiant - // exchange with other zone surfaces | Heat source/sink term for radiant systems | (if there - // is one present) | Radiant flux from high temp radiant heater | Radiant flux from a hot - // water baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from - // an electric baseboard heater | Iterative damping term (for stability) | Current - // conduction from | the outside surface | Coefficient for conduction (current time) | - // Convection and damping term | Radiation from AFN ducts - - state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum); - } - - // Loop over non-window surfaces (includes TubularDaylightingDomes) - for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) { - bool movableInsulPresent = state.dataSurface->AnyMovableInsulation && state.dataHeatBalSurf->SurfMovInsulIntPresent(surfNum); - if (movableInsulPresent) { // Movable insulation present, recalc surface temps - Real64 HMovInsul = state.dataHeatBalSurf->SurfMovInsulHInt(surfNum); - Real64 F1 = HMovInsul / (HMovInsul + state.dataHeatBalSurf->SurfHConvInt(surfNum) + IterDampConst); - state.dataHeatBalSurf->SurfTempIn(surfNum) = - (state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) + - state.dataHeatBalSurf->SurfCTFCross0(surfNum) * state.dataHeatBalSurf->SurfTempOutHist(surfNum) + - F1 * (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) + - state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) + - state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) + - state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) + - IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(surfNum))) / - (state.dataHeatBalSurf->SurfCTFInside0(surfNum) + HMovInsul - F1 * HMovInsul); // Convection from surface to zone air + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst; + int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast; + Real64 const iterDampConstant = IterDampConst; // local for vectorization + // this loop auto-vectorizes + for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) { + // Perform heat balance on the inside face of the surface ... + // The following are possibilities here (this function only does CTF, see CalcHeatBalanceInsideSurf2 for others): + // (a) the surface is a pool (no movable insulation, no source/sink, only CTF solution algorithm) + // (b) the surface is adiabatic (a partition), in which case the temperature of both sides are the same + // (c) standard (or interzone) opaque surface with no movable insulation, normal heat balance equation + // (d) standard (or interzone) window: call to CalcWindowHeatBalance to get window layer temperatures + // (e) standard opaque surface with movable insulation, special two-part equation + // In the surface calculation there are the following Algorithm types for opaque surfaces that + // do not have movable insulation: + // (a) the regular CTF calc (SolutionAlgo = UseCTF) + // (b) the EMPD calc (Solutionalgo = UseEMPD) + // (c) the CondFD calc (SolutionAlgo = UseCondFD) + // (d) the HAMT calc (solutionalgo = UseHAMT). + + // For adiabatic surface: + // Adiabatic: TempDiv = (1.0 / (construct.CTFInside(0) - construct.CTFCross(0) + HConvIn_surf + IterDampConst)); + // Adiabatic: SurfTempInTmp(SurfNum) = (TempTerm + IterDampConst * SurfTempInsOld(SurfNum)) * TempDiv; + // Ad+Source: SurfTempInTmp(SurfNum) = (TempTerm + construct.CTFSourceIn(0) * SurfQsrcHist(SurfNum, 1) + IterDampConst * + // SurfTempInsOld(SurfNum)) * TempDiv; Ad+Pool: TempDiv = (1.0 / (construct.CTFInside(0) - construct.CTFCross(0) + + // PoolHeatTransCoefs(SurfNum) + IterDampConst); Ad+Pool: SurfTempInTmp(SurfNum) = (SurfCTFConstInPart(SurfNum) + + // QPoolSurfNumerator(SurfNum) + IterDampConst * SurfTempInsOld(SurfNum)) * TempDiv; + + // For standard or interzone surface: + // Standard: TempDiv = (1.0 / (construct.CTFInside(0) + HConvIn_surf + IterDampConst)); + // Standard: SurfTempInTmp(SurfNum) = (TempTerm + IterDampConst * SurfTempInsOld(SurfNum) + construct.CTFCross(0) * TH11) * + // TempDiv; Std+Source: SurfTempInTmp(SurfNum) = (TempTerm + construct.CTFSourceIn(0) * SurfQsrcHist(SurfNum, 1) + IterDampConst + // * SurfTempInsOld(SurfNum)) * TempDiv; Std+Pool: TempDiv = (1.0 / (construct.CTFInside(0) + PoolHeatTransCoefs(SurfNum) + + // IterDampConst); Std+Pool: SurfTempInTmp(SurfNum) = (SurfCTFConstInPart(SurfNum) + QPoolSurfNumerator(SurfNum) + + // IterDampConst* SurfTempInsOld(SurfNum) + construct.CTFCross(0) * TH11) * TempDiv; + + // Composite with Adiabatic/Source/Pool flags: + // TempDiv = (1.0 / (construct.CTFInside(0) - SurfIsAdiabatic*construct.CTFCross(0)+ + // SurfIsOperatingPool*PoolHeatTransCoefs(SurfNum) + IsNotPoolSurf*HConvIn_surf + IterDampConst)); + // SurfTempInTmp(SurfNum) = (IsNotPoolSurf*TempTerm + IsSource*construct.CTFSourceIn(0) * SurfQsrcHist(SurfNum, 1) + + // SurfIsOperatingPool*SurfCTFConstInPart(SurfNum) + SurfIsOperatingPool*QPoolSurfNumerator(SurfNum) + // + IterDampConst * SurfTempInsOld(SurfNum)+ + // IsNotAdiabatic*IsNotSource*construct.CTFCross(0) + // * TH11) * TempDiv; + // Calculate the current inside surface temperature state.dataHeatBalSurf->SurfTempInTmp(surfNum) = - (state.dataHeatBalSurf->SurfCTFInside0(surfNum) * state.dataHeatBalSurf->SurfTempIn(surfNum) + - HMovInsul * state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) - - state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) - - state.dataHeatBalSurf->SurfCTFCross0(surfNum) * state.dataHeatBalSurf->SurfTempOutHist(surfNum)) / - (HMovInsul); + ((!state.dataHeatBalSurf->SurfIsOperatingPool(surfNum)) * + (state.dataHeatBalSurf->SurfTempTerm(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum)) + + state.dataHeatBalSurf->SurfIsSourceOrSink(surfNum) * state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) * + state.dataHeatBalSurf->SurfQSourceSinkHist(surfNum) + + state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + + state.dataHeatBalSurf->SurfIsOperatingPool(surfNum) * state.dataHeatBalFanSys->QPoolSurfNumerator(surfNum) + + iterDampConstant * state.dataHeatBalSurf->SurfTempInsOld(surfNum) + + (!state.dataHeatBalSurf->SurfIsAdiabatic(surfNum)) * state.dataHeatBalSurf->SurfCTFCross0(surfNum) * + state.dataHeatBalSurf->SurfTempOutHist(surfNum)) * + state.dataHeatBalSurf->SurfTempDiv(surfNum); + // Constant part of conduction eq (history terms) | LW radiation from internal sources | SW + // radiation from internal sources | Convection from surface to zone air | Net radiant + // exchange with other zone surfaces | Heat source/sink term for radiant systems | (if there + // is one present) | Radiant flux from high temp radiant heater | Radiant flux from a hot + // water baseboard heater | Radiant flux from a steam baseboard heater | Radiant flux from + // an electric baseboard heater | Iterative damping term (for stability) | Current + // conduction from | the outside surface | Coefficient for conduction (current time) | + // Convection and damping term | Radiation from AFN ducts + + state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum); } - if (state.dataHeatBal->AnyInternalHeatSourceInInput) { - if (state.dataConstruction->Construct(Surface(surfNum).Construction).SourceSinkPresent) { - // Set the appropriate parameters for the radiant system - // Radiant system does not need the damping coefficient terms (hopefully) - Real64 const RadSysDiv(1.0 / (state.dataHeatBalSurf->SurfCTFInside0(surfNum) + state.dataHeatBalSurf->SurfHConvInt(surfNum))); - Real64 const TempTerm( - state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) + - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) + - state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) + - state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) + - (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / state.dataGlobal->TimeStepZoneSec)); - state.dataHeatBalFanSys->RadSysTiHBConstCoef(surfNum) = - TempTerm * RadSysDiv; // Constant portion of cond eq (history terms) | LW radiation from internal sources | SW - // radiation from internal sources | Convection from surface to zone air | Radiant flux - // from high temp radiant heater | Radiant flux from a hot water baseboard heater | - // Radiant flux from a steam baseboard heater | Radiant flux from an electric baseboard - // heater | Net radiant exchange with other zone surfaces | Cond term (both partition - // sides same temp) | Convection and damping term - state.dataHeatBalFanSys->RadSysTiHBToutCoef(surfNum) = - state.dataHeatBalSurf->SurfCTFCross0(surfNum) * RadSysDiv; // Outside temp=inside temp for a partition | - // Cond term (both partition sides same temp) | - // Convection and damping term - state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(surfNum) = - state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) * RadSysDiv; // QTF term for the source | Cond term (both - // partition sides same temp) | Convection and - // damping term - - if (Surface(surfNum).ExtBoundCond > 0) { // This is an interzone partition and we need to set outside params - // The inside coefficients of one side are equal to the outside coefficients of the other side. But, - // the inside coefficients are set up once the heat balance equation for that side has been calculated. - // For both sides to actually have been set, we have to wait until we get to the second side in the surface - // derived type. At that point, both inside coefficient sets have been evaluated. - if (Surface(surfNum).ExtBoundCond <= surfNum) { // Both of the inside coefficients have now been set - int OtherSideSurfNum = Surface(surfNum).ExtBoundCond; - state.dataHeatBalFanSys->RadSysToHBConstCoef(OtherSideSurfNum) = - state.dataHeatBalFanSys->RadSysTiHBConstCoef(surfNum); - state.dataHeatBalFanSys->RadSysToHBTinCoef(OtherSideSurfNum) = state.dataHeatBalFanSys->RadSysTiHBToutCoef(surfNum); - state.dataHeatBalFanSys->RadSysToHBQsrcCoef(OtherSideSurfNum) = state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(surfNum); - state.dataHeatBalFanSys->RadSysToHBConstCoef(surfNum) = - state.dataHeatBalFanSys->RadSysTiHBConstCoef(OtherSideSurfNum); - state.dataHeatBalFanSys->RadSysToHBTinCoef(surfNum) = state.dataHeatBalFanSys->RadSysTiHBToutCoef(OtherSideSurfNum); - state.dataHeatBalFanSys->RadSysToHBQsrcCoef(surfNum) = state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(OtherSideSurfNum); + // Loop over non-window surfaces (includes TubularDaylightingDomes) + for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) { + bool movableInsulPresent = state.dataSurface->AnyMovableInsulation && state.dataHeatBalSurf->SurfMovInsulIntPresent(surfNum); + if (movableInsulPresent) { // Movable insulation present, recalc surface temps + Real64 HMovInsul = state.dataHeatBalSurf->SurfMovInsulHInt(surfNum); + Real64 F1 = HMovInsul / (HMovInsul + state.dataHeatBalSurf->SurfHConvInt(surfNum) + IterDampConst); + state.dataHeatBalSurf->SurfTempIn(surfNum) = + (state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) + + state.dataHeatBalSurf->SurfCTFCross0(surfNum) * state.dataHeatBalSurf->SurfTempOutHist(surfNum) + + F1 * (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) + + state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) + + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) + + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) + + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) + + IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(surfNum))) / + (state.dataHeatBalSurf->SurfCTFInside0(surfNum) + HMovInsul - F1 * HMovInsul); // Convection from surface to zone air + + state.dataHeatBalSurf->SurfTempInTmp(surfNum) = + (state.dataHeatBalSurf->SurfCTFInside0(surfNum) * state.dataHeatBalSurf->SurfTempIn(surfNum) + + HMovInsul * state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) - + state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) - + state.dataHeatBalSurf->SurfCTFCross0(surfNum) * state.dataHeatBalSurf->SurfTempOutHist(surfNum)) / + (HMovInsul); + } + + if (state.dataHeatBal->AnyInternalHeatSourceInInput) { + if (state.dataConstruction->Construct(Surface(surfNum).Construction).SourceSinkPresent) { + // Set the appropriate parameters for the radiant system + // Radiant system does not need the damping coefficient terms (hopefully) + Real64 const RadSysDiv(1.0 / + (state.dataHeatBalSurf->SurfCTFInside0(surfNum) + state.dataHeatBalSurf->SurfHConvInt(surfNum))); + Real64 const TempTerm( + state.dataHeatBalSurf->SurfCTFConstInPart(surfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) + + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(surfNum) + + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) + + state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) + + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) + + (state.dataHeatBalFanSys->QRadSurfAFNDuct(surfNum) / state.dataGlobal->TimeStepZoneSec)); + state.dataHeatBalFanSys->RadSysTiHBConstCoef(surfNum) = + TempTerm * RadSysDiv; // Constant portion of cond eq (history terms) | LW radiation from internal sources | SW + // radiation from internal sources | Convection from surface to zone air | Radiant flux + // from high temp radiant heater | Radiant flux from a hot water baseboard heater | + // Radiant flux from a steam baseboard heater | Radiant flux from an electric baseboard + // heater | Net radiant exchange with other zone surfaces | Cond term (both partition + // sides same temp) | Convection and damping term + state.dataHeatBalFanSys->RadSysTiHBToutCoef(surfNum) = + state.dataHeatBalSurf->SurfCTFCross0(surfNum) * RadSysDiv; // Outside temp=inside temp for a partition | + // Cond term (both partition sides same temp) | + // Convection and damping term + state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(surfNum) = + state.dataHeatBalSurf->SurfCTFSourceIn0(surfNum) * RadSysDiv; // QTF term for the source | Cond term (both + // partition sides same temp) | Convection and + // damping term + + if (Surface(surfNum).ExtBoundCond > 0) { // This is an interzone partition and we need to set outside params + // The inside coefficients of one side are equal to the outside coefficients of the other side. But, + // the inside coefficients are set up once the heat balance equation for that side has been calculated. + // For both sides to actually have been set, we have to wait until we get to the second side in the surface + // derived type. At that point, both inside coefficient sets have been evaluated. + if (Surface(surfNum).ExtBoundCond <= surfNum) { // Both of the inside coefficients have now been set + int OtherSideSurfNum = Surface(surfNum).ExtBoundCond; + state.dataHeatBalFanSys->RadSysToHBConstCoef(OtherSideSurfNum) = + state.dataHeatBalFanSys->RadSysTiHBConstCoef(surfNum); + state.dataHeatBalFanSys->RadSysToHBTinCoef(OtherSideSurfNum) = + state.dataHeatBalFanSys->RadSysTiHBToutCoef(surfNum); + state.dataHeatBalFanSys->RadSysToHBQsrcCoef(OtherSideSurfNum) = + state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(surfNum); + state.dataHeatBalFanSys->RadSysToHBConstCoef(surfNum) = + state.dataHeatBalFanSys->RadSysTiHBConstCoef(OtherSideSurfNum); + state.dataHeatBalFanSys->RadSysToHBTinCoef(surfNum) = + state.dataHeatBalFanSys->RadSysTiHBToutCoef(OtherSideSurfNum); + state.dataHeatBalFanSys->RadSysToHBQsrcCoef(surfNum) = + state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(OtherSideSurfNum); + } } } } } - } - // Loop over window surfaces - int const firstWindowSurf = state.dataHeatBal->Zone(zoneNum).WindowSurfaceFirst; - int const lastWindowSurf = state.dataHeatBal->Zone(zoneNum).WindowSurfaceLast; - for (int surfNum = firstWindowSurf; surfNum <= lastWindowSurf; ++surfNum) { - auto &surface(Surface(surfNum)); - if (state.dataSurface->UseRepresentativeSurfaceCalculations) { - int repSurfNum = surface.RepresentativeCalcSurfNum; - if (surfNum != repSurfNum) continue; - } - Real64 &TH11(state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum)); - int const ConstrNum = state.dataSurface->SurfActiveConstruction(surfNum); - auto const &construct(state.dataConstruction->Construct(ConstrNum)); - if (state.dataSurface->SurfWinOriginalClass(surfNum) == SurfaceClass::TDD_Diffuser) { // Tubular daylighting device - // Lookup up the TDD:DOME object - int const pipeNum = state.dataSurface->SurfWinTDDPipeNum(surfNum); - int const domeNum = state.dataDaylightingDevicesData->TDDPipe(pipeNum).Dome; - // Ueff = 1 / effective R value between TDD:DOME and TDD:DIFFUSER - Real64 Ueff = 1.0 / state.dataDaylightingDevicesData->TDDPipe(pipeNum).Reff; - - // Similar to opaque surface but outside surface temp of TDD:DOME is used, and no embedded sources/sinks. - // Absorbed shortwave radiation is treated similar to a regular window, but only 1 glass layer is allowed. - // = SurfWinQRadSWwinAbs(surfNum,1)/2.0 - Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(surfNum) = state.dataHeatBalSurf->SurfHConvInt(surfNum)); - state.dataHeatBalSurf->SurfTempInTmp(surfNum) = - (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) + state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, 1) / 2.0 + - state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) + - HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) + - IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(surfNum) + - Ueff * state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum)) / - (Ueff + HConvIn_surf + IterDampConst); // LW radiation from internal sources | SW radiation from internal sources and - // solar | Convection from surface to zone air | Net radiant exchange with - // other zone surfaces | Iterative damping term (for stability) | Current - // conduction from the outside surface | Coefficient for conduction (current - // time) | Convection and damping term - state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum); - Real64 const Sigma_Temp_4(DataGlobalConstants::StefanBoltzmann * - pow_4(state.dataHeatBalSurf->SurfTempIn(surfNum) + DataGlobalConstants::KelvinConv)); - - // Calculate window heat gain for TDD:DIFFUSER since this calculation is usually done in WindowManager - if (state.dataHeatBalSurf->AnyRadiantSystems(surfNum)) - state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) = GetSurfQdotRadHVACInPerArea(state, surfNum); - state.dataSurface->SurfWinHeatGain(surfNum) = - state.dataSurface->SurfWinTransSolar(surfNum) + - HConvIn_surf * surface.Area * (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum)) + - state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal * surface.Area * + // Loop over window surfaces + int const firstWindowSurf = thisSpace.WindowSurfaceFirst; + int const lastWindowSurf = thisSpace.WindowSurfaceLast; + for (int surfNum = firstWindowSurf; surfNum <= lastWindowSurf; ++surfNum) { + auto &surface(Surface(surfNum)); + if (state.dataSurface->UseRepresentativeSurfaceCalculations) { + int repSurfNum = surface.RepresentativeCalcSurfNum; + if (surfNum != repSurfNum) continue; + } + Real64 &TH11(state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum)); + int const ConstrNum = state.dataSurface->SurfActiveConstruction(surfNum); + auto const &construct(state.dataConstruction->Construct(ConstrNum)); + if (state.dataSurface->SurfWinOriginalClass(surfNum) == SurfaceClass::TDD_Diffuser) { // Tubular daylighting device + // Lookup up the TDD:DOME object + int const pipeNum = state.dataSurface->SurfWinTDDPipeNum(surfNum); + int const domeNum = state.dataDaylightingDevicesData->TDDPipe(pipeNum).Dome; + // Ueff = 1 / effective R value between TDD:DOME and TDD:DIFFUSER + Real64 Ueff = 1.0 / state.dataDaylightingDevicesData->TDDPipe(pipeNum).Reff; + + // Similar to opaque surface but outside surface temp of TDD:DOME is used, and no embedded sources/sinks. + // Absorbed shortwave radiation is treated similar to a regular window, but only 1 glass layer is allowed. + // = SurfWinQRadSWwinAbs(surfNum,1)/2.0 + Real64 const HConvIn_surf(state.dataMstBal->HConvInFD(surfNum) = state.dataHeatBalSurf->SurfHConvInt(surfNum)); + state.dataHeatBalSurf->SurfTempInTmp(surfNum) = + (state.dataHeatBal->SurfQdotRadIntGainsInPerArea(surfNum) + state.dataHeatBal->SurfWinQRadSWwinAbs(surfNum, 1) / 2.0 + + state.dataHeatBalSurf->SurfQAdditionalHeatSourceInside(surfNum) + + HConvIn_surf * state.dataHeatBalSurfMgr->RefAirTemp(surfNum) + + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(surfNum) + + IterDampConst * state.dataHeatBalSurf->SurfTempInsOld(surfNum) + + Ueff * state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum)) / + (Ueff + HConvIn_surf + IterDampConst); // LW radiation from internal sources | SW radiation from internal sources and + // solar | Convection from surface to zone air | Net radiant exchange with + // other zone surfaces | Iterative damping term (for stability) | Current + // conduction from the outside surface | Coefficient for conduction (current + // time) | Convection and damping term + state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum); + Real64 const Sigma_Temp_4(DataGlobalConstants::StefanBoltzmann * + pow_4(state.dataHeatBalSurf->SurfTempIn(surfNum) + DataGlobalConstants::KelvinConv)); + + // Calculate window heat gain for TDD:DIFFUSER since this calculation is usually done in WindowManager + if (state.dataHeatBalSurf->AnyRadiantSystems(surfNum)) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum) = GetSurfQdotRadHVACInPerArea(state, surfNum); + state.dataSurface->SurfWinHeatGain(surfNum) = + state.dataSurface->SurfWinTransSolar(surfNum) + + HConvIn_surf * surface.Area * + (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum)) + + state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal * surface.Area * + (Sigma_Temp_4 - + (state.dataSurface->SurfWinIRfromParentZone(surfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum))) - + state.dataHeatBal->EnclSolQSWRad(surface.SolarEnclIndex) * surface.Area * + state.dataConstruction->Construct(surface.Construction) + .TransDiff; // Transmitted solar | Convection | IR exchange | IR + // Zone diffuse interior shortwave reflected back into the TDD + + // fill out report vars for components of Window Heat Gain + state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) = + HConvIn_surf * surface.Area * + (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum)); + state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = + state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal * surface.Area * (Sigma_Temp_4 - - (state.dataSurface->SurfWinIRfromParentZone(surfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum))) - - state.dataHeatBal->EnclSolQSWRad(surface.SolarEnclIndex) * surface.Area * - state.dataConstruction->Construct(surface.Construction).TransDiff; // Transmitted solar | Convection | IR exchange | IR - // Zone diffuse interior shortwave reflected back into the TDD - - // fill out report vars for components of Window Heat Gain - state.dataSurface->SurfWinGainConvGlazToZoneRep(surfNum) = - HConvIn_surf * surface.Area * (state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurfMgr->RefAirTemp(surfNum)); - state.dataSurface->SurfWinGainIRGlazToZoneRep(surfNum) = - state.dataConstruction->Construct(surface.Construction).InsideAbsorpThermal * surface.Area * - (Sigma_Temp_4 - - (state.dataSurface->SurfWinIRfromParentZone(surfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum))); - state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) = state.dataHeatBal->EnclSolQSWRad(surface.SolarEnclIndex) * - surface.Area * - state.dataConstruction->Construct(surface.Construction).TransDiff; - } else { // Regular window - if (state.dataHeatBal->InsideSurfIterations == 0) { // Do windows only once - // Get outside convection coeff for exterior window here to avoid calling - // InitExteriorConvectionCoeff from CalcWindowHeatBalance, which avoids circular reference - // (HeatBalanceSurfaceManager USEing and WindowManager and - // WindowManager USEing HeatBalanceSurfaceManager) - if (surface.ExtBoundCond == ExternalEnvironment) { - DataSurfaces::SurfaceRoughness RoughSurf = - state.dataMaterial->Material(construct.LayerPoint(1)).Roughness; // Outside surface roughness - Real64 EmisOut = - state.dataMaterial->Material(construct.LayerPoint(1)).AbsorpThermalFront; // Glass outside surface emissivity - auto const shading_flag(state.dataSurface->SurfWinShadingFlag(surfNum)); - if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(shading_flag)) { - // Exterior shade in place - int const ConstrNumSh = Surface(surfNum).activeShadedConstruction; - if (ConstrNumSh != 0) { - RoughSurf = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumSh).LayerPoint(1)).Roughness; - EmisOut = - state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumSh).LayerPoint(1)).AbsorpThermal; + (state.dataSurface->SurfWinIRfromParentZone(surfNum) + state.dataHeatBalSurf->SurfQdotRadHVACInPerArea(surfNum))); + state.dataSurface->SurfWinLossSWZoneToOutWinRep(surfNum) = state.dataHeatBal->EnclSolQSWRad(surface.SolarEnclIndex) * + surface.Area * + state.dataConstruction->Construct(surface.Construction).TransDiff; + } else { // Regular window + if (state.dataHeatBal->InsideSurfIterations == 0) { // Do windows only once + // Get outside convection coeff for exterior window here to avoid calling + // InitExteriorConvectionCoeff from CalcWindowHeatBalance, which avoids circular reference + // (HeatBalanceSurfaceManager USEing and WindowManager and + // WindowManager USEing HeatBalanceSurfaceManager) + if (surface.ExtBoundCond == ExternalEnvironment) { + DataSurfaces::SurfaceRoughness RoughSurf = + state.dataMaterial->Material(construct.LayerPoint(1)).Roughness; // Outside surface roughness + Real64 EmisOut = + state.dataMaterial->Material(construct.LayerPoint(1)).AbsorpThermalFront; // Glass outside surface emissivity + auto const shading_flag(state.dataSurface->SurfWinShadingFlag(surfNum)); + if (ANY_EXTERIOR_SHADE_BLIND_SCREEN(shading_flag)) { + // Exterior shade in place + int const ConstrNumSh = Surface(surfNum).activeShadedConstruction; + if (ConstrNumSh != 0) { + RoughSurf = + state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumSh).LayerPoint(1)).Roughness; + EmisOut = + state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNumSh).LayerPoint(1)).AbsorpThermal; + } } - } - // Get the outside effective emissivity for Equivalent layer model - if (construct.WindowTypeEQL) { - EmisOut = WindowEquivalentLayer::EQLWindowOutsideEffectiveEmiss(state, ConstrNum); - } - // Set Exterior Convection Coefficient... - if (state.dataSurface->SurfExtConvCoeffIndex(surfNum) > 0) { - - state.dataHeatBalSurf->SurfHcExt(surfNum) = ConvectionCoefficients::SetExtConvectionCoeff(state, surfNum); - - } else if (surface.ExtWind) { // Window is exposed to wind (and possibly rain) - - // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in - // subroutine) - ConvectionCoefficients::InitExteriorConvectionCoeff(state, - surfNum, - 0.0, - RoughSurf, - EmisOut, - TH11, - state.dataHeatBalSurf->SurfHcExt(surfNum), - state.dataHeatBalSurf->SurfHSkyExt(surfNum), - state.dataHeatBalSurf->SurfHGrdExt(surfNum), - state.dataHeatBalSurf->SurfHAirExt(surfNum)); - - if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside window surface gets wet - state.dataHeatBalSurf->SurfHcExt(surfNum) = 1000.0; // Reset SurfHcExt because of wetness + // Get the outside effective emissivity for Equivalent layer model + if (construct.WindowTypeEQL) { + EmisOut = WindowEquivalentLayer::EQLWindowOutsideEffectiveEmiss(state, ConstrNum); } + // Set Exterior Convection Coefficient... + if (state.dataSurface->SurfExtConvCoeffIndex(surfNum) > 0) { + + state.dataHeatBalSurf->SurfHcExt(surfNum) = ConvectionCoefficients::SetExtConvectionCoeff(state, surfNum); + + } else if (surface.ExtWind) { // Window is exposed to wind (and possibly rain) + + // Calculate exterior heat transfer coefficients with windspeed (windspeed is calculated internally in + // subroutine) + ConvectionCoefficients::InitExteriorConvectionCoeff(state, + surfNum, + 0.0, + RoughSurf, + EmisOut, + TH11, + state.dataHeatBalSurf->SurfHcExt(surfNum), + state.dataHeatBalSurf->SurfHSkyExt(surfNum), + state.dataHeatBalSurf->SurfHGrdExt(surfNum), + state.dataHeatBalSurf->SurfHAirExt(surfNum)); + + if (state.dataEnvrn->IsRain) { // Raining: since wind exposed, outside window surface gets wet + state.dataHeatBalSurf->SurfHcExt(surfNum) = 1000.0; // Reset SurfHcExt because of wetness + } - } else { // Not Wind exposed - - // Calculate exterior heat transfer coefficients for windspeed = 0 - ConvectionCoefficients::InitExteriorConvectionCoeff(state, - surfNum, - 0.0, - RoughSurf, - EmisOut, - TH11, - state.dataHeatBalSurf->SurfHcExt(surfNum), - state.dataHeatBalSurf->SurfHSkyExt(surfNum), - state.dataHeatBalSurf->SurfHGrdExt(surfNum), - state.dataHeatBalSurf->SurfHAirExt(surfNum)); - } + } else { // Not Wind exposed + + // Calculate exterior heat transfer coefficients for windspeed = 0 + ConvectionCoefficients::InitExteriorConvectionCoeff(state, + surfNum, + 0.0, + RoughSurf, + EmisOut, + TH11, + state.dataHeatBalSurf->SurfHcExt(surfNum), + state.dataHeatBalSurf->SurfHSkyExt(surfNum), + state.dataHeatBalSurf->SurfHGrdExt(surfNum), + state.dataHeatBalSurf->SurfHAirExt(surfNum)); + } - } else { // Interior Surface + } else { // Interior Surface - if (state.dataSurface->SurfExtConvCoeffIndex(surfNum) > 0) { - state.dataHeatBalSurf->SurfHcExt(surfNum) = ConvectionCoefficients::SetExtConvectionCoeff(state, surfNum); - } else { - // Exterior Convection Coefficient for the Interior or Interzone Window is the Interior Convection Coeff of - // same - state.dataHeatBalSurf->SurfHcExt(surfNum) = state.dataHeatBalSurf->SurfHConvInt(surface.ExtBoundCond); + if (state.dataSurface->SurfExtConvCoeffIndex(surfNum) > 0) { + state.dataHeatBalSurf->SurfHcExt(surfNum) = ConvectionCoefficients::SetExtConvectionCoeff(state, surfNum); + } else { + // Exterior Convection Coefficient for the Interior or Interzone Window is the Interior Convection Coeff of + // same + state.dataHeatBalSurf->SurfHcExt(surfNum) = state.dataHeatBalSurf->SurfHConvInt(surface.ExtBoundCond); + } } - } - // Following call determines inside surface temperature of glazing, and of - // frame and/or divider, if present - CalcWindowHeatBalance( - state, surfNum, state.dataHeatBalSurf->SurfHcExt(surfNum), state.dataHeatBalSurf->SurfTempInTmp(surfNum), TH11); + // Following call determines inside surface temperature of glazing, and of + // frame and/or divider, if present + CalcWindowHeatBalance( + state, surfNum, state.dataHeatBalSurf->SurfHcExt(surfNum), state.dataHeatBalSurf->SurfTempInTmp(surfNum), TH11); - state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum); + state.dataHeatBalSurf->SurfTempIn(surfNum) = state.dataHeatBalSurf->SurfTempInTmp(surfNum); + } } } - } - int const firstSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrWinSurfaceFirst; - int const lastSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrWinSurfaceLast; - for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - auto &zone(state.dataHeatBal->Zone(zoneNum)); - - Real64 &TH11(state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum)); - Real64 &TH12(state.dataHeatBalSurf->SurfInsideTempHist(1)(surfNum)); - TH12 = state.dataHeatBalSurf->SurfTempIn(surfNum); - state.dataHeatBalSurf->SurfTempOut(surfNum) = TH11; // For reporting - if (state.dataSurface->SurfWinOriginalClass(surfNum) == SurfaceClass::TDD_Diffuser) { // Tubular daylighting device - // Tubular daylighting devices are treated as one big object with an effective R value. - // The outside face temperature of the TDD:DOME and the inside face temperature of the - // TDD:DIFFUSER are calculated with the outside and inside heat balances respectively. - // Below, the resulting temperatures are copied to the inside face of the TDD:DOME - // and the outside face of the TDD:DIFFUSER for reporting. - - // Set inside temp variables of TDD:DOME equal to inside temp of TDD:DIFFUSER - int domeNum = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(surfNum)).Dome; - state.dataHeatBalSurf->SurfInsideTempHist(1)(domeNum) = state.dataHeatBalSurf->SurfTempIn(domeNum) = - state.dataHeatBalSurf->SurfTempInTmp(domeNum) = state.dataHeatBalSurf->SurfTempIn(surfNum); - - // Set outside temp reporting variable of TDD:DOME (since it gets skipped otherwise) - // Reset outside temp variables of TDD:DIFFUSER equal to outside temp of TDD:DOME - TH11 = state.dataHeatBalSurf->SurfTempOut(surfNum) = state.dataHeatBalSurf->SurfTempOut(domeNum) = - state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum); - } + int const firstSurf = thisSpace.OpaqOrWinSurfaceFirst; + int const lastSurf = thisSpace.OpaqOrWinSurfaceLast; + for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { + auto &zone(state.dataHeatBal->Zone(zoneNum)); + + Real64 &TH11(state.dataHeatBalSurf->SurfOutsideTempHist(1)(surfNum)); + Real64 &TH12(state.dataHeatBalSurf->SurfInsideTempHist(1)(surfNum)); + TH12 = state.dataHeatBalSurf->SurfTempIn(surfNum); + state.dataHeatBalSurf->SurfTempOut(surfNum) = TH11; // For reporting + if (state.dataSurface->SurfWinOriginalClass(surfNum) == SurfaceClass::TDD_Diffuser) { // Tubular daylighting device + // Tubular daylighting devices are treated as one big object with an effective R value. + // The outside face temperature of the TDD:DOME and the inside face temperature of the + // TDD:DIFFUSER are calculated with the outside and inside heat balances respectively. + // Below, the resulting temperatures are copied to the inside face of the TDD:DOME + // and the outside face of the TDD:DIFFUSER for reporting. + + // Set inside temp variables of TDD:DOME equal to inside temp of TDD:DIFFUSER + int domeNum = state.dataDaylightingDevicesData->TDDPipe(state.dataSurface->SurfWinTDDPipeNum(surfNum)).Dome; + state.dataHeatBalSurf->SurfInsideTempHist(1)(domeNum) = state.dataHeatBalSurf->SurfTempIn(domeNum) = + state.dataHeatBalSurf->SurfTempInTmp(domeNum) = state.dataHeatBalSurf->SurfTempIn(surfNum); + + // Set outside temp reporting variable of TDD:DOME (since it gets skipped otherwise) + // Reset outside temp variables of TDD:DIFFUSER equal to outside temp of TDD:DOME + TH11 = state.dataHeatBalSurf->SurfTempOut(surfNum) = state.dataHeatBalSurf->SurfTempOut(domeNum) = + state.dataHeatBalSurf->SurfOutsideTempHist(1)(domeNum); + } - if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimit) || (TH12 < MinSurfaceTempLimit)) { - TestSurfTempCalcHeatBalanceInsideSurf(state, TH12, surfNum, zone, state.dataHeatBalSurfMgr->calcHeatBalInsideSurfWarmupErrCount); + if ((TH12 > state.dataHeatBalSurf->MaxSurfaceTempLimit) || (TH12 < MinSurfaceTempLimit)) { + TestSurfTempCalcHeatBalanceInsideSurf( + state, TH12, surfNum, zone, state.dataHeatBalSurfMgr->calcHeatBalInsideSurfWarmupErrCount); + } } } } // ...end of main loops over all surfaces for inside heat balances @@ -8803,12 +8927,15 @@ void CalcHeatBalanceInsideSurf2CTFOnly(EnergyPlusData &state, // Convergence check - Loop through all relevant non-window surfaces to check for convergence... Real64 MaxDelTemp = 0.0; // Maximum change in surface temperature for any opaque surface from one iteration to the next for (int zoneNum = FirstZone; zoneNum <= LastZone; ++zoneNum) { - int const firstNonWinSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceFirst; - int const lastNonWinSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceLast; - for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) { - Real64 delta = state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurf->SurfTempInsOld(surfNum); - Real64 absDif = std::abs(delta); - MaxDelTemp = std::max(absDif, MaxDelTemp); + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstNonWinSurf = thisSpace.OpaqOrIntMassSurfaceFirst; + int const lastNonWinSurf = thisSpace.OpaqOrIntMassSurfaceLast; + for (int surfNum = firstNonWinSurf; surfNum <= lastNonWinSurf; ++surfNum) { + Real64 delta = state.dataHeatBalSurf->SurfTempIn(surfNum) - state.dataHeatBalSurf->SurfTempInsOld(surfNum); + Real64 absDif = std::abs(delta); + MaxDelTemp = std::max(absDif, MaxDelTemp); + } } } // ...end of loop to check for convergence @@ -9066,7 +9193,6 @@ void CalcOutsideSurfTemp(EnergyPlusData &state, // Using/Aliasing using namespace DataEnvironment; - using namespace DataHeatBalFanSys; using namespace DataHeatBalance; using namespace DataHeatBalSurface; using namespace DataSurfaces; @@ -9136,7 +9262,7 @@ void CalcOutsideSurfTemp(EnergyPlusData &state, state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) * TSky + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + F1 * (state.dataHeatBal->SurfWinQRadSWwinAbs(SurfNum2, 1) / 2.0 + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum2) + - state.dataHeatBalSurf->SurfHConvInt(SurfNum2) * state.dataHeatBalFanSys->MAT(ZoneNum2) + + state.dataHeatBalSurf->SurfHConvInt(SurfNum2) * state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum2).MAT + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum2))) / (Ueff + state.dataHeatBalSurf->SurfHcExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) - @@ -9201,7 +9327,7 @@ void CalcOutsideSurfTemp(EnergyPlusData &state, construct.CTFSourceOut(0) * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) + F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) + - state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataHeatBalFanSys->MAT(ZoneNum) + + state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) / (construct.CTFOutside(0) + state.dataHeatBalSurf->SurfHcExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) - @@ -9214,7 +9340,7 @@ void CalcOutsideSurfTemp(EnergyPlusData &state, state.dataHeatBalSurf->SurfHGrdExt(SurfNum) * TGround + F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) + - state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataHeatBalFanSys->MAT(ZoneNum) + + state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) / (construct.CTFOutside(0) + state.dataHeatBalSurf->SurfHcExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum) + state.dataHeatBalSurf->SurfHSkyExt(SurfNum) + state.dataHeatBalSurf->SurfHGrdExt(SurfNum) - @@ -9233,7 +9359,7 @@ void CalcOutsideSurfTemp(EnergyPlusData &state, F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) + construct.CTFSourceIn(0) * state.dataHeatBalSurf->SurfQsrcHist(SurfNum, 1) + - state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataHeatBalFanSys->MAT(ZoneNum) + + state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) / (construct.CTFOutside(0) + state.dataHeatBalSurf->SurfHcExt(SurfNum) + HRad - F1 * construct.CTFCross(0)); // MAT use here is problem for room air models @@ -9242,7 +9368,7 @@ void CalcOutsideSurfTemp(EnergyPlusData &state, state.dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(SurfNum) + HRad * RadTemp + F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) + - state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataHeatBalFanSys->MAT(ZoneNum) + + state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum))) / (construct.CTFOutside(0) + state.dataHeatBalSurf->SurfHcExt(SurfNum) + HRad - F1 * construct.CTFCross(0)); // MAT use here is problem for room air models @@ -9272,7 +9398,7 @@ void CalcOutsideSurfTemp(EnergyPlusData &state, state.dataHeatBalSurf->SurfQRadLWOutSrdSurfs(SurfNum) + F1 * (state.dataHeatBalSurf->SurfCTFConstInPart(SurfNum) + state.dataHeatBalSurf->SurfOpaqQRadSWInAbs(SurfNum) + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) + - state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataHeatBalFanSys->MAT(ZoneNum) + + state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT + state.dataHeatBalSurf->SurfQdotRadNetLWInPerArea(SurfNum)) + F2 * (state.dataHeatBalSurf->SurfQRadSWOutMvIns(SurfNum) + (state.dataHeatBalSurf->SurfHcExt(SurfNum) + state.dataHeatBalSurf->SurfHAirExt(SurfNum)) * TempExt + diff --git a/src/EnergyPlus/HighTempRadiantSystem.cc b/src/EnergyPlus/HighTempRadiantSystem.cc index be01b15102e..ff962bd4c21 100644 --- a/src/EnergyPlus/HighTempRadiantSystem.cc +++ b/src/EnergyPlus/HighTempRadiantSystem.cc @@ -73,6 +73,7 @@ #include #include #include +#include namespace EnergyPlus { @@ -763,7 +764,7 @@ namespace HighTempRadiantSystem { if (state.dataGlobal->BeginTimeStepFlag && FirstHVACIteration) { // This is the first pass through in a particular time step ZoneNum = state.dataHighTempRadSys->HighTempRadSys(RadSysNum).ZonePtr; state.dataHighTempRadSys->ZeroSourceSumHATsurf(ZoneNum) = - SumHATsurf(state, ZoneNum); // Set this to figure out what part of the load the radiant system meets + state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state); // Set this to figure out what part of the load the radiant system meets state.dataHighTempRadSys->QHTRadSrcAvg(RadSysNum) = 0.0; // Initialize this variable to zero (radiant system defaults to off) state.dataHighTempRadSys->LastQHTRadSrc(RadSysNum) = 0.0; // At the beginning of a time step, reset to zero so average calculation can start again @@ -950,18 +951,20 @@ namespace HighTempRadiantSystem { // Determine the current setpoint temperature and the temperature at which the unit should be completely off SetPtTemp = GetCurrentScheduleValue(state, state.dataHighTempRadSys->HighTempRadSys(RadSysNum).SetptSchedPtr); OffTemp = SetPtTemp + 0.5 * state.dataHighTempRadSys->HighTempRadSys(RadSysNum).ThrottlRange; - OpTemp = (state.dataHeatBalFanSys->MAT(ZoneNum) + state.dataHeatBal->ZoneMRT(ZoneNum)) / 2.0; // Approximate the "operative" temperature + OpTemp = (state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT + state.dataHeatBal->ZoneMRT(ZoneNum)) / + 2.0; // Approximate the "operative" temperature // Determine the fraction of maximum power to the unit (limiting the fraction range from zero to unity) switch (state.dataHighTempRadSys->HighTempRadSys(RadSysNum).ControlType) { case RadControlType::MATControl: { - HeatFrac = (OffTemp - state.dataHeatBalFanSys->MAT(ZoneNum)) / state.dataHighTempRadSys->HighTempRadSys(RadSysNum).ThrottlRange; + HeatFrac = (OffTemp - state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT) / + state.dataHighTempRadSys->HighTempRadSys(RadSysNum).ThrottlRange; } break; case RadControlType::MRTControl: { HeatFrac = (OffTemp - state.dataHeatBal->ZoneMRT(ZoneNum)) / state.dataHighTempRadSys->HighTempRadSys(RadSysNum).ThrottlRange; } break; case RadControlType::OperativeControl: { - OpTemp = 0.5 * (state.dataHeatBalFanSys->MAT(ZoneNum) + state.dataHeatBal->ZoneMRT(ZoneNum)); + OpTemp = 0.5 * (state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT + state.dataHeatBal->ZoneMRT(ZoneNum)); HeatFrac = (OffTemp - OpTemp) / state.dataHighTempRadSys->HighTempRadSys(RadSysNum).ThrottlRange; } break; default: @@ -1062,13 +1065,13 @@ namespace HighTempRadiantSystem { // Determine the proper temperature on which to control switch (state.dataHighTempRadSys->HighTempRadSys(RadSysNum).ControlType) { case RadControlType::MATSPControl: { - ZoneTemp = state.dataHeatBalFanSys->MAT(ZoneNum); + ZoneTemp = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; } break; case RadControlType::MRTSPControl: { ZoneTemp = state.dataHeatBal->ZoneMRT(ZoneNum); } break; case RadControlType::OperativeSPControl: { - ZoneTemp = 0.5 * (state.dataHeatBalFanSys->MAT(ZoneNum) + state.dataHeatBal->ZoneMRT(ZoneNum)); + ZoneTemp = 0.5 * (state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT + state.dataHeatBal->ZoneMRT(ZoneNum)); } break; default: { assert(false); @@ -1106,13 +1109,13 @@ namespace HighTempRadiantSystem { // Redetermine the current value of the controlling temperature switch (state.dataHighTempRadSys->HighTempRadSys(RadSysNum).ControlType) { case RadControlType::MATControl: { - ZoneTemp = state.dataHeatBalFanSys->MAT(ZoneNum); + ZoneTemp = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; } break; case RadControlType::MRTControl: { ZoneTemp = state.dataHeatBal->ZoneMRT(ZoneNum); } break; case RadControlType::OperativeControl: { - ZoneTemp = 0.5 * (state.dataHeatBalFanSys->MAT(ZoneNum) + state.dataHeatBal->ZoneMRT(ZoneNum)); + ZoneTemp = 0.5 * (state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT + state.dataHeatBal->ZoneMRT(ZoneNum)); } break; default: break; @@ -1235,7 +1238,7 @@ namespace HighTempRadiantSystem { LoadMet = 0.0; // System wasn't running so it can't meet a load } else { ZoneNum = state.dataHighTempRadSys->HighTempRadSys(RadSysNum).ZonePtr; - LoadMet = (SumHATsurf(state, ZoneNum) - state.dataHighTempRadSys->ZeroSourceSumHATsurf(ZoneNum)) + + LoadMet = (state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state) - state.dataHighTempRadSys->ZeroSourceSumHATsurf(ZoneNum)) + state.dataHeatBalFanSys->SumConvHTRadSys(ZoneNum); } } @@ -1437,72 +1440,6 @@ namespace HighTempRadiantSystem { state.dataHighTempRadSys->HighTempRadSys(RadSysNum).HeatPower * TimeStepSys * DataGlobalConstants::SecInHour; } - Real64 SumHATsurf(EnergyPlusData &state, int const ZoneNum) // Zone number - { - - // FUNCTION INFORMATION: - // AUTHOR Peter Graham Ellis - // DATE WRITTEN July 2003 - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS FUNCTION: - // This function calculates the zone sum of Hc*Area*Tsurf. It replaces the old SUMHAT. - // The SumHATsurf code below is also in the CalcZoneSums subroutine in ZoneTempPredictorCorrector - // and should be updated accordingly. - - // METHODOLOGY EMPLOYED: - // na - - // REFERENCES: - // na - - // Using/Aliasing - using namespace DataSurfaces; - using namespace DataHeatBalance; - - // Return value - Real64 SumHATsurf; - - // Locals - // FUNCTION ARGUMENT DEFINITIONS: - - // FUNCTION LOCAL VARIABLE DECLARATIONS: - int SurfNum; // Surface number - Real64 Area; // Effective surface area - - SumHATsurf = 0.0; - - for (SurfNum = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst; SurfNum <= state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast; ++SurfNum) { - - Area = state.dataSurface->Surface(SurfNum).Area; - - if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Window) { - if (ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum))) { - // The area is the shade or blind area = the sum of the glazing area and the divider area (which is zero if no divider) - Area += state.dataSurface->SurfWinDividerArea(SurfNum); - } - - if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) { - // Window frame contribution - SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinFrameArea(SurfNum) * - (1.0 + state.dataSurface->SurfWinProjCorrFrIn(SurfNum)) * state.dataSurface->SurfWinFrameTempIn(SurfNum); - } - - if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0 && - !ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum))) { - // Window divider contribution (only from shade or blind for window with divider and interior shade or blind) - SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinDividerArea(SurfNum) * - (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) * state.dataSurface->SurfWinDividerTempIn(SurfNum); - } - } - - SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * Area * state.dataHeatBalSurf->SurfTempInTmp(SurfNum); - } - - return SumHATsurf; - } - } // namespace HighTempRadiantSystem } // namespace EnergyPlus diff --git a/src/EnergyPlus/HighTempRadiantSystem.hh b/src/EnergyPlus/HighTempRadiantSystem.hh index 12cddb5966b..3523ff6600a 100644 --- a/src/EnergyPlus/HighTempRadiantSystem.hh +++ b/src/EnergyPlus/HighTempRadiantSystem.hh @@ -192,8 +192,6 @@ namespace HighTempRadiantSystem { void ReportHighTempRadiantSystem(EnergyPlusData &state, int RadSysNum); // Index for the low temperature radiant system under consideration within the derived types - Real64 SumHATsurf(EnergyPlusData &state, int const ZoneNum); // Zone number - } // namespace HighTempRadiantSystem struct HighTempRadiantSystemData : BaseGlobalStruct diff --git a/src/EnergyPlus/HybridModel.cc b/src/EnergyPlus/HybridModel.cc index a10e85594f3..6ae06d678fa 100644 --- a/src/EnergyPlus/HybridModel.cc +++ b/src/EnergyPlus/HybridModel.cc @@ -128,10 +128,9 @@ namespace HybridModel { // Read hybrid model input CurrentModuleObject = "HybridModel:Zone"; state.dataHybridModel->NumOfHybridModelZones = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject); - state.dataHybridModel->HybridModelZone.allocate(state.dataGlobal->NumOfZones); if (state.dataHybridModel->NumOfHybridModelZones > 0) { - + state.dataHybridModel->HybridModelZone.allocate(state.dataGlobal->NumOfZones); for (int HybridModelNum = 1; HybridModelNum <= state.dataHybridModel->NumOfHybridModelZones; ++HybridModelNum) { state.dataInputProcessing->inputProcessor->getObjectItem(state, @@ -491,6 +490,10 @@ namespace HybridModel { ShowWarningError(state, "Room Air Model Type should be Mixing if Hybrid Modeling is performed for the zone."); } } + if (state.dataHeatBal->doSpaceHeatBalanceSimulation || state.dataHeatBal->doSpaceHeatBalanceSizing) { + ShowSevereError(state, "Hybrid Modeling is not supported with ZoneAirHeatBalanceAlgorithm Space Heat Balance."); + ErrorsFound = true; + } } if (ErrorsFound) { diff --git a/src/EnergyPlus/InternalHeatGains.cc b/src/EnergyPlus/InternalHeatGains.cc index 7369eeb6532..08ffb21fcc2 100644 --- a/src/EnergyPlus/InternalHeatGains.cc +++ b/src/EnergyPlus/InternalHeatGains.cc @@ -62,7 +62,6 @@ #include #include #include -#include #include #include #include @@ -95,6 +94,7 @@ #include #include #include +#include namespace EnergyPlus { @@ -6955,6 +6955,7 @@ namespace InternalHeatGains { // The reported temperature range. for (int Loop = 1; Loop <= state.dataHeatBal->TotPeople; ++Loop) { int NZ = state.dataHeatBal->People(Loop).ZonePtr; + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ); NumberOccupants = state.dataHeatBal->People(Loop).NumberOfPeople * GetCurrentScheduleValue(state, state.dataHeatBal->People(Loop).NumberOfPeoplePtr); if (state.dataHeatBal->People(Loop).EMSPeopleOn) NumberOccupants = state.dataHeatBal->People(Loop).EMSNumberOfPeople; @@ -6967,21 +6968,16 @@ namespace InternalHeatGains { TotalPeopleGain = NumberOccupants * ActivityLevel_WperPerson; // if the user did not specify a sensible fraction, calculate the sensible heat gain if (state.dataHeatBal->People(Loop).UserSpecSensFrac == DataGlobalConstants::AutoCalculate) { - if (!(state.dataRoomAirMod->IsZoneDV(NZ) || state.dataRoomAirMod->IsZoneUI(NZ))) { - SensiblePeopleGain = - NumberOccupants * - (C[0] + ActivityLevel_WperPerson * (C[1] + ActivityLevel_WperPerson * C[2]) + - state.dataHeatBalFanSys->MAT(NZ) * - ((C[3] + ActivityLevel_WperPerson * (C[4] + ActivityLevel_WperPerson * C[5])) + - state.dataHeatBalFanSys->MAT(NZ) * (C[6] + ActivityLevel_WperPerson * (C[7] + ActivityLevel_WperPerson * C[8])))); - } else { // UCSD - DV or UI - SensiblePeopleGain = - NumberOccupants * - (C[0] + ActivityLevel_WperPerson * (C[1] + ActivityLevel_WperPerson * C[2]) + - state.dataRoomAirMod->TCMF(NZ) * - ((C[3] + ActivityLevel_WperPerson * (C[4] + ActivityLevel_WperPerson * C[5])) + - state.dataRoomAirMod->TCMF(NZ) * (C[6] + ActivityLevel_WperPerson * (C[7] + ActivityLevel_WperPerson * C[8])))); + Real64 airTemp = thisZoneHB.MAT; + if (state.dataRoomAirMod->anyNonMixingRoomAirModel) { + if (state.dataRoomAirMod->IsZoneDV(NZ) || state.dataRoomAirMod->IsZoneUI(NZ)) { + airTemp = state.dataRoomAirMod->TCMF(NZ); + } } + SensiblePeopleGain = + NumberOccupants * (C[0] + ActivityLevel_WperPerson * (C[1] + ActivityLevel_WperPerson * C[2]) + + airTemp * ((C[3] + ActivityLevel_WperPerson * (C[4] + ActivityLevel_WperPerson * C[5])) + + airTemp * (C[6] + ActivityLevel_WperPerson * (C[7] + ActivityLevel_WperPerson * C[8])))); } else { // if the user did specify a sensible fraction, use it SensiblePeopleGain = TotalPeopleGain * state.dataHeatBal->People(Loop).UserSpecSensFrac; } @@ -7302,10 +7298,11 @@ namespace InternalHeatGains { for (int NZ = 1; NZ <= state.dataGlobal->NumOfZones; ++NZ) { - state.dataHeatBalFanSys->ZoneLatentGain(NZ) = InternalHeatGains::SumAllInternalLatentGains(state, NZ); + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ); + thisZoneHB.ZoneLatentGain = InternalHeatGains::SumAllInternalLatentGains(state, NZ); // Also sets space gains // Added for hybrid model if (state.dataHybridModel->FlagHybridModel_PC) { - state.dataHeatBalFanSys->ZoneLatentGainExceptPeople(NZ) = InternalHeatGains::SumAllInternalLatentGainsExceptPeople(state, NZ); + thisZoneHB.ZoneLatentGainExceptPeople = InternalHeatGains::SumAllInternalLatentGainsExceptPeople(state, NZ); // Also sets space gains } } @@ -7319,38 +7316,39 @@ namespace InternalHeatGains { } } - state.dataHeatBalFanSys->SumConvHTRadSys = 0.0; - pulseMultipler = 0.01; // the W/sqft pulse for the zone if (state.dataGlobal->CompLoadReportIsReq) { AllocateLoadComponentArrays(state); } for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { // Loop through all surfaces... - int const firstSurf = state.dataHeatBal->Zone(zoneNum).HTSurfaceFirst; - int const lastSurf = state.dataHeatBal->Zone(zoneNum).HTSurfaceLast; - if (firstSurf <= 0) continue; - for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) { - auto &thisEnclosure(state.dataViewFactor->EnclRadInfo(state.dataSurface->Surface(SurfNum).RadEnclIndex)); - - if (!state.dataGlobal->doLoadComponentPulseNow) { - state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) = - thisEnclosure.radQThermalRad * thisEnclosure.radThermAbsMult * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum); - } else { - state.dataInternalHeatGains->curQL = thisEnclosure.radQThermalRad; - // for the loads component report during the special sizing run increase the radiant portion - // a small amount to create a "pulse" of heat that is used for the delayed loads - state.dataInternalHeatGains->adjQL = state.dataInternalHeatGains->curQL + thisEnclosure.FloorArea * pulseMultipler; - // ITABSF is the Inside Thermal Absorptance - // EnclRadThermAbsMult is a multiplier for each zone - // SurfQdotRadIntGainsInPerArea is the thermal radiation absorbed on inside surfaces - state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) = - state.dataInternalHeatGains->adjQL * thisEnclosure.radThermAbsMult * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum); - // store the magnitude and time of the pulse - state.dataOutRptTab->radiantPulseTimestep(state.dataSize->CurOverallSimDay, zoneNum) = - (state.dataGlobal->HourOfDay - 1) * state.dataGlobal->NumOfTimeStepInHour + state.dataGlobal->TimeStep; - state.dataOutRptTab->radiantPulseReceived(state.dataSize->CurOverallSimDay, SurfNum) = - (state.dataInternalHeatGains->adjQL - state.dataInternalHeatGains->curQL) * thisEnclosure.radThermAbsMult * - state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) * state.dataSurface->Surface(SurfNum).Area; + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurf = thisSpace.HTSurfaceFirst; + int const lastSurf = thisSpace.HTSurfaceLast; + if (firstSurf <= 0) continue; + for (int SurfNum = firstSurf; SurfNum <= lastSurf; ++SurfNum) { + auto &thisEnclosure(state.dataViewFactor->EnclRadInfo(state.dataSurface->Surface(SurfNum).RadEnclIndex)); + + if (!state.dataGlobal->doLoadComponentPulseNow) { + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) = + thisEnclosure.radQThermalRad * thisEnclosure.radThermAbsMult * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum); + } else { + state.dataInternalHeatGains->curQL = thisEnclosure.radQThermalRad; + // for the loads component report during the special sizing run increase the radiant portion + // a small amount to create a "pulse" of heat that is used for the delayed loads + state.dataInternalHeatGains->adjQL = state.dataInternalHeatGains->curQL + thisEnclosure.FloorArea * pulseMultipler; + // ITABSF is the Inside Thermal Absorptance + // EnclRadThermAbsMult is a multiplier for each zone + // SurfQdotRadIntGainsInPerArea is the thermal radiation absorbed on inside surfaces + state.dataHeatBal->SurfQdotRadIntGainsInPerArea(SurfNum) = + state.dataInternalHeatGains->adjQL * thisEnclosure.radThermAbsMult * state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum); + // store the magnitude and time of the pulse + state.dataOutRptTab->radiantPulseTimestep(state.dataSize->CurOverallSimDay, zoneNum) = + (state.dataGlobal->HourOfDay - 1) * state.dataGlobal->NumOfTimeStepInHour + state.dataGlobal->TimeStep; + state.dataOutRptTab->radiantPulseReceived(state.dataSize->CurOverallSimDay, SurfNum) = + (state.dataInternalHeatGains->adjQL - state.dataInternalHeatGains->curQL) * thisEnclosure.radThermAbsMult * + state.dataHeatBalSurf->SurfAbsThermalInt(SurfNum) * state.dataSurface->Surface(SurfNum).Area; + } } } } @@ -7531,6 +7529,7 @@ namespace InternalHeatGains { for (Loop = 1; Loop <= state.dataHeatBal->TotITEquip; ++Loop) { // Get schedules NZ = state.dataHeatBal->ZoneITEq(Loop).ZonePtr; + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ); int spaceNum = state.dataHeatBal->ZoneITEq(Loop).spaceIndex; OperSchedFrac = GetCurrentScheduleValue(state, state.dataHeatBal->ZoneITEq(Loop).OperSchedPtr); CPULoadSchedFrac = GetCurrentScheduleValue(state, state.dataHeatBal->ZoneITEq(Loop).CPULoadSchedPtr); @@ -7558,25 +7557,25 @@ namespace InternalHeatGains { } else { RecircFrac = state.dataHeatBal->ZoneITEq(Loop).DesignRecircFrac; } - TRecirc = state.dataHeatBalFanSys->MAT(NZ); - WRecirc = state.dataHeatBalFanSys->ZoneAirHumRat(NZ); + TRecirc = thisZoneHB.MAT; + WRecirc = thisZoneHB.ZoneAirHumRat; TAirIn = TRecirc * RecircFrac + TSupply * (1.0 - RecircFrac); WAirIn = WRecirc * RecircFrac + WSupply * (1.0 - RecircFrac); } else if (AirConnection == ITEInletConnection::RoomAirModel) { // Room air model option: TAirIn=TAirZone, according to EngineeringRef 17.1.4 - TAirIn = state.dataHeatBalFanSys->MAT(NZ); + TAirIn = thisZoneHB.MAT; TSupply = TAirIn; - WAirIn = state.dataHeatBalFanSys->ZoneAirHumRat(NZ); + WAirIn = thisZoneHB.ZoneAirHumRat; } else { // TAirIn = TRoomAirNodeIn, according to EngineeringRef 17.1.4 if (state.dataHeatBal->ZoneITEq(Loop).inControlledZone) { int ZoneAirInletNode = state.dataZoneEquip->ZoneEquipConfig(NZ).InletNode(1); TSupply = state.dataLoopNodes->Node(ZoneAirInletNode).Temp; } else { - TSupply = state.dataHeatBalFanSys->MAT(NZ); + TSupply = thisZoneHB.MAT; } - TAirIn = state.dataHeatBalFanSys->MAT(NZ); - WAirIn = state.dataHeatBalFanSys->ZoneAirHumRat(NZ); + TAirIn = thisZoneHB.MAT; + WAirIn = thisZoneHB.ZoneAirHumRat; } } TDPAirIn = PsyTdpFnWPb(state, WAirIn, state.dataEnvrn->StdBaroPress, RoutineName); @@ -8427,10 +8426,11 @@ namespace InternalHeatGains { } if (ReSumLatentGains) { for (int NZ = 1; NZ <= state.dataGlobal->NumOfZones; ++NZ) { - state.dataHeatBalFanSys->ZoneLatentGain(NZ) = InternalHeatGains::SumAllInternalLatentGains(state, NZ); + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ); + thisZoneHB.ZoneLatentGain = InternalHeatGains::SumAllInternalLatentGains(state, NZ); // Added for the hybrid model if (state.dataHybridModel->FlagHybridModel_PC) { - state.dataHeatBalFanSys->ZoneLatentGainExceptPeople(NZ) = InternalHeatGains::SumAllInternalLatentGainsExceptPeople(state, NZ); + thisZoneHB.ZoneLatentGainExceptPeople = InternalHeatGains::SumAllInternalLatentGainsExceptPeople(state, NZ); } } } @@ -8443,11 +8443,25 @@ namespace InternalHeatGains { } } - Real64 SumAllInternalConvectionGains(EnergyPlusData &state, - int const ZoneNum // zone index pointer for which zone to sum gains for + Real64 zoneSumAllInternalConvectionGains(EnergyPlusData &state, + int const zoneNum // zone index pointer to sum gains for ) { + Real64 zoneSumConvGainRate(0.0); + // worker routine for summing all the internal gain types + + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + if (state.dataHeatBal->spaceIntGainDevices(spaceNum).numberOfDevices == 0) continue; + zoneSumConvGainRate += InternalHeatGains::spaceSumAllInternalConvectionGains(state, spaceNum); + } + + return zoneSumConvGainRate; + } + Real64 spaceSumAllInternalConvectionGains(EnergyPlusData &state, + int const spaceNum // space index pointer to sum gains for + ) + { // SUBROUTINE INFORMATION: // AUTHOR B. Griffith // DATE WRITTEN Nov. 2011 @@ -8455,20 +8469,12 @@ namespace InternalHeatGains { // PURPOSE OF THIS SUBROUTINE: // worker routine for summing all the internal gain types - // Return value - Real64 SumConvGainRate(0.0); + Real64 spaceSumConvGainRate(0.0); - for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { - if (state.dataHeatBal->spaceIntGainDevices(spaceNum).numberOfDevices == 0) { - continue; - } - - for (int DeviceNum = 1; DeviceNum <= state.dataHeatBal->spaceIntGainDevices(spaceNum).numberOfDevices; ++DeviceNum) { - SumConvGainRate += state.dataHeatBal->spaceIntGainDevices(spaceNum).device(DeviceNum).ConvectGainRate; - } + for (int DeviceNum = 1; DeviceNum <= state.dataHeatBal->spaceIntGainDevices(spaceNum).numberOfDevices; ++DeviceNum) { + spaceSumConvGainRate += state.dataHeatBal->spaceIntGainDevices(spaceNum).device(DeviceNum).ConvectGainRate; } - - return SumConvGainRate; + return spaceSumConvGainRate; } // For HybridModel @@ -8540,9 +8546,23 @@ namespace InternalHeatGains { return SumConvGainRate; } - Real64 SumAllReturnAirConvectionGains(EnergyPlusData &state, - int const ZoneNum, // zone index pointer for which zone to sum gains for - int const ReturnNodeNum // return air node number + Real64 zoneSumAllReturnAirConvectionGains(EnergyPlusData &state, + int const zoneNum, // zone index pointer to sum gains for + int const returnNodeNum // return air node number + ) + { + Real64 zoneSumReturnAirGainRate = 0.0; + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + if (state.dataHeatBal->spaceIntGainDevices(spaceNum).numberOfDevices == 0) continue; + zoneSumReturnAirGainRate += InternalHeatGains::spaceSumAllReturnAirConvectionGains(state, spaceNum, returnNodeNum); + } + + return zoneSumReturnAirGainRate; + } + + Real64 spaceSumAllReturnAirConvectionGains(EnergyPlusData &state, + int const spaceNum, // space index pointer to sum gains for + int const returnNodeNum // return air node number ) { @@ -8553,23 +8573,16 @@ namespace InternalHeatGains { // PURPOSE OF THIS SUBROUTINE: // worker routine for summing all the internal gain types - // Return value - Real64 SumReturnAirGainRate(0.0); + Real64 spaceSumReturnAirGainRate = 0.0; - for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { - if (state.dataHeatBal->spaceIntGainDevices(spaceNum).numberOfDevices == 0) { - continue; - } - - for (int DeviceNum = 1; DeviceNum <= state.dataHeatBal->spaceIntGainDevices(spaceNum).numberOfDevices; ++DeviceNum) { - // If ReturnNodeNum is zero, sum for entire zone, otherwise sum only for specified ReturnNodeNum - if ((ReturnNodeNum == 0) || (ReturnNodeNum == state.dataHeatBal->spaceIntGainDevices(spaceNum).device(DeviceNum).ReturnAirNodeNum)) { - SumReturnAirGainRate += state.dataHeatBal->spaceIntGainDevices(spaceNum).device(DeviceNum).ReturnAirConvGainRate; - } + for (int DeviceNum = 1; DeviceNum <= state.dataHeatBal->spaceIntGainDevices(spaceNum).numberOfDevices; ++DeviceNum) { + // If ReturnNodeNum is zero, sum for entire zone, otherwise sum only for specified ReturnNodeNum + if ((returnNodeNum == 0) || (returnNodeNum == state.dataHeatBal->spaceIntGainDevices(spaceNum).device(DeviceNum).ReturnAirNodeNum)) { + spaceSumReturnAirGainRate += state.dataHeatBal->spaceIntGainDevices(spaceNum).device(DeviceNum).ReturnAirConvGainRate; } } - return SumReturnAirGainRate; + return spaceSumReturnAirGainRate; } Real64 SumReturnAirConvectionGainsByTypes( @@ -8705,6 +8718,7 @@ namespace InternalHeatGains { for (int DeviceNum = 1; DeviceNum <= state.dataHeatBal->spaceIntGainDevices(spaceNum).numberOfDevices; ++DeviceNum) { SumLatentGainRate += state.dataHeatBal->spaceIntGainDevices(spaceNum).device(DeviceNum).LatentGainRate; } + state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).ZoneLatentGain = SumLatentGainRate; } return SumLatentGainRate; @@ -8728,6 +8742,7 @@ namespace InternalHeatGains { SumLatentGainRateExceptPeople += state.dataHeatBal->spaceIntGainDevices(spaceNum).device(DeviceNum).LatentGainRate; } } + state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).ZoneLatentGainExceptPeople = SumLatentGainRateExceptPeople; } return SumLatentGainRateExceptPeople; diff --git a/src/EnergyPlus/InternalHeatGains.hh b/src/EnergyPlus/InternalHeatGains.hh index 588bd629078..408c72bd0e6 100644 --- a/src/EnergyPlus/InternalHeatGains.hh +++ b/src/EnergyPlus/InternalHeatGains.hh @@ -110,8 +110,11 @@ namespace InternalHeatGains { void UpdateInternalGainValues(EnergyPlusData &state, Optional_bool_const SuppressRadiationUpdate = _, Optional_bool_const SumLatentGains = _); - Real64 SumAllInternalConvectionGains(EnergyPlusData &state, - int const ZoneNum); // zone index pointer for which zone to sum gains for + Real64 zoneSumAllInternalConvectionGains(EnergyPlusData &state, + int const zoneNum); // zone index pointer to sum gains for + + Real64 spaceSumAllInternalConvectionGains(EnergyPlusData &state, + int const spaceNum); // space index pointer to sum gains for Real64 SumAllInternalConvectionGainsExceptPeople(EnergyPlusData &state, int const ZoneNum); // zone index pointer for which zone to sum gains for @@ -151,9 +154,14 @@ namespace InternalHeatGains { const Array1D &FractionARR // array of fractional multipliers to apply to devices ); - Real64 SumAllReturnAirConvectionGains(EnergyPlusData &state, - int const ZoneNum, // zone index pointer for which zone to sum gains for - int const ReturnNodeNum // return air node number + Real64 zoneSumAllReturnAirConvectionGains(EnergyPlusData &state, + int const zoneNum, // zone index pointer to sum gains for + int const returnNodeNum // return air node number + ); + + Real64 spaceSumAllReturnAirConvectionGains(EnergyPlusData &state, + int const spaceNum, // space index pointer to sum gains for + int const returnNodeNum // return air node number ); Real64 SumReturnAirConvectionGainsByTypes( diff --git a/src/EnergyPlus/LowTempRadiantSystem.cc b/src/EnergyPlus/LowTempRadiantSystem.cc index d300b4fad88..ec23eae6dfb 100644 --- a/src/EnergyPlus/LowTempRadiantSystem.cc +++ b/src/EnergyPlus/LowTempRadiantSystem.cc @@ -2421,7 +2421,7 @@ namespace LowTempRadiantSystem { case LowTempRadiantSystem::SystemType::HydronicSystem: { ZoneNum = state.dataLowTempRadSys->HydrRadSys(RadSysNum).ZonePtr; state.dataLowTempRadSys->ZeroSourceSumHATsurf(ZoneNum) = - SumHATsurf(state, ZoneNum); // Set this to figure what part of the load the radiant system meets + state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state); // Set this to figure what part of the load the radiant system meets for (RadSurfNum = 1; RadSurfNum <= state.dataLowTempRadSys->HydrRadSys(RadSysNum).NumOfSurfaces; ++RadSurfNum) { SurfNum = state.dataLowTempRadSys->HydrRadSys(RadSysNum).SurfacePtr(RadSurfNum); state.dataLowTempRadSys->QRadSysSrcAvg(SurfNum) = 0.0; // Initialize this variable to zero (radiant system defaults to off) @@ -2436,7 +2436,7 @@ namespace LowTempRadiantSystem { case LowTempRadiantSystem::SystemType::ConstantFlowSystem: { ZoneNum = state.dataLowTempRadSys->CFloRadSys(RadSysNum).ZonePtr; state.dataLowTempRadSys->ZeroSourceSumHATsurf(ZoneNum) = - SumHATsurf(state, ZoneNum); // Set this to figure what part of the load the radiant system meets + state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state); // Set this to figure what part of the load the radiant system meets for (RadSurfNum = 1; RadSurfNum <= state.dataLowTempRadSys->CFloRadSys(RadSysNum).NumOfSurfaces; ++RadSurfNum) { SurfNum = state.dataLowTempRadSys->CFloRadSys(RadSysNum).SurfacePtr(RadSurfNum); state.dataLowTempRadSys->QRadSysSrcAvg(SurfNum) = 0.0; // Initialize this variable to zero (radiant system defaults to off) @@ -2451,7 +2451,7 @@ namespace LowTempRadiantSystem { case LowTempRadiantSystem::SystemType::ElectricSystem: { ZoneNum = state.dataLowTempRadSys->ElecRadSys(RadSysNum).ZonePtr; state.dataLowTempRadSys->ZeroSourceSumHATsurf(ZoneNum) = - SumHATsurf(state, ZoneNum); // Set this to figure what part of the load the radiant system meets + state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state); // Set this to figure what part of the load the radiant system meets for (RadSurfNum = 1; RadSurfNum <= state.dataLowTempRadSys->ElecRadSys(RadSysNum).NumOfSurfaces; ++RadSurfNum) { SurfNum = state.dataLowTempRadSys->ElecRadSys(RadSysNum).SurfacePtr(RadSurfNum); state.dataLowTempRadSys->QRadSysSrcAvg(SurfNum) = 0.0; // Initialize this variable to zero (radiant system defaults to off) @@ -3937,7 +3937,8 @@ namespace LowTempRadiantSystem { // A safety parameter is added (hardwired parameter) to avoid getting too close to condensation // conditions. this->CondCausedShutDown = false; - DewPointTemp = PsyTdpFnWPb(state, state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum), state.dataEnvrn->OutBaroPress); + DewPointTemp = + PsyTdpFnWPb(state, state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZoneAirHumRat, state.dataEnvrn->OutBaroPress); if ((this->OperatingMode == CoolingMode) && (variableFlowDesignDataObject.CondCtrlType == CondContrlType::CondCtrlSimpleOff)) { @@ -4163,7 +4164,7 @@ namespace LowTempRadiantSystem { HeatBalanceSurfaceManager::CalcHeatBalanceOutsideSurf(state, ZoneNum); HeatBalanceSurfaceManager::CalcHeatBalanceInsideSurf(state, ZoneNum); - LoadMet = SumHATsurf(state, ZoneNum) - state.dataLowTempRadSys->ZeroSourceSumHATsurf(ZoneNum); + LoadMet = state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state) - state.dataLowTempRadSys->ZeroSourceSumHATsurf(ZoneNum); } void ConstantFlowRadiantSystemData::calculateLowTemperatureRadiantSystem(EnergyPlusData &state, @@ -5029,7 +5030,8 @@ namespace LowTempRadiantSystem { // A safety parameter is added (hardwired parameter) to avoid getting too close to condensation // conditions. this->CondCausedShutDown = false; - DewPointTemp = PsyTdpFnWPb(state, state.dataHeatBalFanSys->ZoneAirHumRat(this->ZonePtr), state.dataEnvrn->OutBaroPress); + DewPointTemp = + PsyTdpFnWPb(state, state.dataZoneTempPredictorCorrector->zoneHeatBalance(this->ZonePtr).ZoneAirHumRat, state.dataEnvrn->OutBaroPress); if ((this->OperatingMode == CoolingMode) && (ConstantFlowDesignDataObject.CondCtrlType == CondContrlType::CondCtrlSimpleOff)) { @@ -5179,7 +5181,7 @@ namespace LowTempRadiantSystem { HeatBalanceSurfaceManager::CalcHeatBalanceOutsideSurf(state, ZoneNum); HeatBalanceSurfaceManager::CalcHeatBalanceInsideSurf(state, ZoneNum); - LoadMet = SumHATsurf(state, this->ZonePtr) - state.dataLowTempRadSys->ZeroSourceSumHATsurf(this->ZonePtr); + LoadMet = state.dataHeatBal->Zone(this->ZonePtr).sumHATsurf(state) - state.dataLowTempRadSys->ZeroSourceSumHATsurf(this->ZonePtr); } // TODO Write unit tests for baseboard void ConstantFlowRadiantSystemData::calculateRunningMeanAverageTemperature(EnergyPlusData &state, int RadSysNum) @@ -5311,7 +5313,7 @@ namespace LowTempRadiantSystem { HeatBalanceSurfaceManager::CalcHeatBalanceOutsideSurf(state, ZoneNum); HeatBalanceSurfaceManager::CalcHeatBalanceInsideSurf(state, ZoneNum); - LoadMet = SumHATsurf(state, ZoneNum) - state.dataLowTempRadSys->ZeroSourceSumHATsurf(ZoneNum); + LoadMet = state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state) - state.dataLowTempRadSys->ZeroSourceSumHATsurf(ZoneNum); } else { // OFF or COOLING MODE (not allowed for an electric low temperature radiant system), turn it off @@ -5587,13 +5589,14 @@ namespace LowTempRadiantSystem { Real64 RadiantSystemBaseData::setRadiantSystemControlTemperature(EnergyPlusData &state, LowTempRadiantControlTypes TempControlType) { + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(this->ZonePtr); switch (TempControlType) { case LowTempRadiantControlTypes::MATControl: - return state.dataHeatBalFanSys->MAT(this->ZonePtr); + return thisZoneHB.MAT; case LowTempRadiantControlTypes::MRTControl: return state.dataHeatBal->ZoneMRT(this->ZonePtr); case LowTempRadiantControlTypes::OperativeControl: - return 0.5 * (state.dataHeatBalFanSys->MAT(this->ZonePtr) + state.dataHeatBal->ZoneMRT(this->ZonePtr)); + return 0.5 * (thisZoneHB.MAT + state.dataHeatBal->ZoneMRT(this->ZonePtr)); case LowTempRadiantControlTypes::ODBControl: return state.dataHeatBal->Zone(this->ZonePtr).OutDryBulbTemp; case LowTempRadiantControlTypes::OWBControl: @@ -5944,56 +5947,6 @@ namespace LowTempRadiantSystem { } } - Real64 SumHATsurf(EnergyPlusData &state, int const ZoneNum) // Zone number - { - - // FUNCTION INFORMATION: - // AUTHOR Peter Graham Ellis - // DATE WRITTEN July 2003 - - // PURPOSE OF THIS FUNCTION: - // This function calculates the zone sum of Hc*Area*Tsurf. It replaces the old SUMHAT. - // The SumHATsurf code below is also in the CalcZoneSums subroutine in ZoneTempPredictorCorrector - // and should be updated accordingly. - - // Using/Aliasing - using namespace DataSurfaces; - using namespace DataHeatBalance; - - // Return value - Real64 sumHATsurf(0.0); - - auto &Surface(state.dataSurface->Surface); - - for (int surfNum = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst; surfNum <= state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast; ++surfNum) { - Real64 Area = Surface(surfNum).Area; - - if (Surface(surfNum).Class == SurfaceClass::Window) { - if (ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(surfNum))) { - // The area is the shade or blind are = sum of the glazing area and the divider area (which is zero if no divider) - Area += state.dataSurface->SurfWinDividerArea(surfNum); - } - - if (state.dataSurface->SurfWinFrameArea(surfNum) > 0.0) { - // Window frame contribution - sumHATsurf += state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataSurface->SurfWinFrameArea(surfNum) * - (1.0 + state.dataSurface->SurfWinProjCorrFrIn(surfNum)) * state.dataSurface->SurfWinFrameTempIn(surfNum); - } - - if (state.dataSurface->SurfWinDividerArea(surfNum) > 0.0 && - !ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(surfNum))) { - // Window divider contribution (only from shade or blind for window with divider and interior shade or blind) - sumHATsurf += state.dataHeatBalSurf->SurfHConvInt(surfNum) * state.dataSurface->SurfWinDividerArea(surfNum) * - (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivIn(surfNum)) * state.dataSurface->SurfWinDividerTempIn(surfNum); - } - } - - sumHATsurf += state.dataHeatBalSurf->SurfHConvInt(surfNum) * Area * state.dataHeatBalSurf->SurfTempInTmp(surfNum); - } - - return sumHATsurf; - } - void VariableFlowRadiantSystemData::reportLowTemperatureRadiantSystem([[maybe_unused]] EnergyPlusData &state) { diff --git a/src/EnergyPlus/LowTempRadiantSystem.hh b/src/EnergyPlus/LowTempRadiantSystem.hh index e5b0456ad4e..398ef3992f2 100644 --- a/src/EnergyPlus/LowTempRadiantSystem.hh +++ b/src/EnergyPlus/LowTempRadiantSystem.hh @@ -531,8 +531,6 @@ namespace LowTempRadiantSystem { void UpdateRadSysSourceValAvg(EnergyPlusData &state, bool &LowTempRadSysOn); // .TRUE. if the radiant system has run this zone time step - Real64 SumHATsurf(EnergyPlusData &state, int const ZoneNum); // Zone number - } // namespace LowTempRadiantSystem struct LowTempRadiantSystemData : BaseGlobalStruct diff --git a/src/EnergyPlus/MicroCHPElectricGenerator.cc b/src/EnergyPlus/MicroCHPElectricGenerator.cc index edb75f7c2e0..50949348bf8 100644 --- a/src/EnergyPlus/MicroCHPElectricGenerator.cc +++ b/src/EnergyPlus/MicroCHPElectricGenerator.cc @@ -60,7 +60,6 @@ #include #include #include -#include #include #include #include @@ -78,6 +77,7 @@ #include #include #include +#include namespace EnergyPlus::MicroCHPElectricGenerator { @@ -880,7 +880,7 @@ void MicroCHPDataStruct::CalcMicroCHPNoNormalizeGeneratorModel(EnergyPlusData &s Real64 thisAmbientTemp; if (this->ZoneID > 0) { - thisAmbientTemp = state.dataHeatBalFanSys->MAT(this->ZoneID); + thisAmbientTemp = state.dataZoneTempPredictorCorrector->zoneHeatBalance(this->ZoneID).MAT; } else { // outdoor location, no zone thisAmbientTemp = state.dataEnvrn->OutDryBulbTemp; } diff --git a/src/EnergyPlus/MoistureBalanceEMPDManager.cc b/src/EnergyPlus/MoistureBalanceEMPDManager.cc index cc2081034d6..fb4d6b0af2f 100644 --- a/src/EnergyPlus/MoistureBalanceEMPDManager.cc +++ b/src/EnergyPlus/MoistureBalanceEMPDManager.cc @@ -56,7 +56,6 @@ #include #include #include -#include #include #include #include @@ -69,6 +68,7 @@ #include #include #include +#include namespace EnergyPlus::MoistureBalanceEMPDManager { @@ -360,10 +360,11 @@ void InitMoistureBalanceEMPD(EnergyPlusData &state) for (SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) { ZoneNum = state.dataSurface->Surface(SurfNum).Zone; if (!state.dataSurface->Surface(SurfNum).HeatTransSurf) continue; - Real64 const rv_air_in_initval = min(PsyRhovFnTdbWPb_fast(state.dataHeatBalFanSys->MAT(ZoneNum), - max(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum), 1.0e-5), - state.dataEnvrn->OutBaroPress), - PsyRhovFnTdbRh(state, state.dataHeatBalFanSys->MAT(ZoneNum), 1.0, "InitMoistureBalanceEMPD")); + Real64 const rv_air_in_initval = + min(PsyRhovFnTdbWPb_fast(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT, + max(state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZoneAirHumRat, 1.0e-5), + state.dataEnvrn->OutBaroPress), + PsyRhovFnTdbRh(state, state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT, 1.0, "InitMoistureBalanceEMPD")); state.dataMstBalEMPD->RVSurfaceOld(SurfNum) = rv_air_in_initval; state.dataMstBalEMPD->RVSurface(SurfNum) = rv_air_in_initval; state.dataMstBalEMPD->RVSurfLayer(SurfNum) = rv_air_in_initval; @@ -548,7 +549,8 @@ void CalcMoistureBalanceEMPD(EnergyPlusData &state, auto const &material(state.dataMaterial->Material(MatNum)); if (material.EMPDmu <= 0.0) { - rv_surface = PsyRhovFnTdbWPb(TempZone, state.dataHeatBalFanSys->ZoneAirHumRat(surface.Zone), state.dataEnvrn->OutBaroPress); + rv_surface = PsyRhovFnTdbWPb( + TempZone, state.dataZoneTempPredictorCorrector->zoneHeatBalance(surface.Zone).ZoneAirHumRat, state.dataEnvrn->OutBaroPress); return; } diff --git a/src/EnergyPlus/MundtSimMgr.cc b/src/EnergyPlus/MundtSimMgr.cc index dfea734e4e9..dff3308b1c6 100644 --- a/src/EnergyPlus/MundtSimMgr.cc +++ b/src/EnergyPlus/MundtSimMgr.cc @@ -64,6 +64,7 @@ #include #include #include +#include namespace EnergyPlus { @@ -158,9 +159,6 @@ namespace MundtSimMgr { // initialize Mundt-model variables // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int SurfNum; // index for surfaces - int SurfFirst; // index number for the first surface in the specified zone - int NumOfSurfs; // number of the first surface in the specified zone int NodeNum; // index for air nodes int ZoneIndex; // index for zones int NumOfAirNodes; // total number of nodes in each zone @@ -177,12 +175,9 @@ namespace MundtSimMgr { bool AirNodeFoundFlag; // flag used for error check bool ErrorsFound; // true if errors found in init - auto &Zone(state.dataHeatBal->Zone); - // allocate and initialize zone data state.dataMundtSimMgr->ZoneData.allocate(state.dataGlobal->NumOfZones); for (auto &e : state.dataMundtSimMgr->ZoneData) { - e.SurfFirst = 0; e.NumOfSurfs = 0; e.MundtZoneIndex = 0; } @@ -195,20 +190,26 @@ namespace MundtSimMgr { MaxNumOfRoomNodes = 0; ErrorsFound = false; for (ZoneIndex = 1; ZoneIndex <= state.dataGlobal->NumOfZones; ++ZoneIndex) { + auto &thisZone = state.dataHeatBal->Zone(ZoneIndex); if (state.dataRoomAirMod->AirModel(ZoneIndex).AirModelType == DataRoomAirModel::RoomAirModel::Mundt) { // find number of zones using the Mundt model ++NumOfMundtZones; // find maximum number of surfaces in zones using the Mundt model - SurfFirst = Zone(ZoneIndex).HTSurfaceFirst; - NumOfSurfs = Zone(ZoneIndex).HTSurfaceLast - SurfFirst + 1; - MaxNumOfSurfs = max(MaxNumOfSurfs, NumOfSurfs); - // fine maximum number of air nodes in zones using the Mundt model - NumOfAirNodes = state.dataRoomAirMod->TotNumOfZoneAirNodes(ZoneIndex); - MaxNumOfAirNodes = max(MaxNumOfAirNodes, NumOfAirNodes); - // assign zone data - state.dataMundtSimMgr->ZoneData(ZoneIndex).SurfFirst = SurfFirst; - state.dataMundtSimMgr->ZoneData(ZoneIndex).NumOfSurfs = NumOfSurfs; - state.dataMundtSimMgr->ZoneData(ZoneIndex).MundtZoneIndex = NumOfMundtZones; + int NumOfSurfs = 0; + for (int spaceNum : thisZone.spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int surfNum = thisSpace.HTSurfaceFirst; surfNum <= thisSpace.HTSurfaceLast; ++surfNum) { + state.dataMundtSimMgr->ZoneData(ZoneIndex).HBsurfaceIndexes.emplace_back(surfNum); + ++NumOfSurfs; + } + MaxNumOfSurfs = max(MaxNumOfSurfs, NumOfSurfs); + // find maximum number of air nodes in zones using the Mundt model + NumOfAirNodes = state.dataRoomAirMod->TotNumOfZoneAirNodes(ZoneIndex); + MaxNumOfAirNodes = max(MaxNumOfAirNodes, NumOfAirNodes); + // assign zone data + state.dataMundtSimMgr->ZoneData(ZoneIndex).NumOfSurfs = NumOfSurfs; + state.dataMundtSimMgr->ZoneData(ZoneIndex).MundtZoneIndex = NumOfMundtZones; + } } } @@ -217,7 +218,7 @@ namespace MundtSimMgr { state.dataMundtSimMgr->TheseSurfIDs.allocate(MaxNumOfSurfs); state.dataMundtSimMgr->MundtAirSurf.allocate(MaxNumOfSurfs, NumOfMundtZones); state.dataMundtSimMgr->LineNode.allocate(MaxNumOfAirNodes, NumOfMundtZones); - for (SurfNum = 1; SurfNum <= MaxNumOfSurfs; ++SurfNum) + for (int SurfNum = 1; SurfNum <= MaxNumOfSurfs; ++SurfNum) state.dataMundtSimMgr->ID1dSurf(SurfNum) = SurfNum; for (auto &e : state.dataMundtSimMgr->MundtAirSurf) { e.Area = 0.0; @@ -234,14 +235,13 @@ namespace MundtSimMgr { // get constant data (unchanged over time) for surfaces and air nodes for (MundtZoneIndex = 1; MundtZoneIndex <= NumOfMundtZones; ++MundtZoneIndex) { - for (ZoneIndex = 1; ZoneIndex <= state.dataGlobal->NumOfZones; ++ZoneIndex) { - + auto &thisZone = state.dataHeatBal->Zone(ZoneIndex); if (state.dataMundtSimMgr->ZoneData(ZoneIndex).MundtZoneIndex == MundtZoneIndex) { // get surface data - for (SurfNum = 1; SurfNum <= state.dataMundtSimMgr->ZoneData(ZoneIndex).NumOfSurfs; ++SurfNum) { - state.dataMundtSimMgr->MundtAirSurf(SurfNum, MundtZoneIndex).Area = - state.dataSurface->Surface(state.dataMundtSimMgr->ZoneData(ZoneIndex).SurfFirst + SurfNum - 1).Area; + for (int surfNum = 1; surfNum <= state.dataMundtSimMgr->ZoneData(ZoneIndex).NumOfSurfs; ++surfNum) { + state.dataMundtSimMgr->MundtAirSurf(surfNum, MundtZoneIndex).Area = + state.dataSurface->Surface(state.dataMundtSimMgr->ZoneData(ZoneIndex).HBsurfaceIndexes(surfNum)).Area; } // get air node data @@ -263,7 +263,7 @@ namespace MundtSimMgr { AirNodeFoundFlag = false; for (AirNodeNum = AirNodeBeginNum; AirNodeNum <= state.dataRoomAirMod->TotNumOfAirNodes; ++AirNodeNum) { - if (UtilityRoutines::SameString(state.dataRoomAirMod->AirNode(AirNodeNum).ZoneName, Zone(ZoneIndex).Name)) { + if (UtilityRoutines::SameString(state.dataRoomAirMod->AirNode(AirNodeNum).ZoneName, thisZone.Name)) { state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).ClassType = state.dataRoomAirMod->AirNode(AirNodeNum).ClassType; state.dataMundtSimMgr->LineNode(NodeNum, MundtZoneIndex).AirNodeName = state.dataRoomAirMod->AirNode(AirNodeNum).Name; @@ -287,7 +287,7 @@ namespace MundtSimMgr { // error check for debugging if (!AirNodeFoundFlag) { - ShowSevereError(state, "InitMundtModel: Air Node in Zone=\"" + Zone(ZoneIndex).Name + "\" is not found."); + ShowSevereError(state, "InitMundtModel: Air Node in Zone=\"" + thisZone.Name + "\" is not found."); ErrorsFound = true; continue; } @@ -329,40 +329,15 @@ namespace MundtSimMgr { // DATE WRITTEN April 2003 // MODIFIED July 2003 (CC) // February 2004, fix allocate-deallocate problem (CC) - // RE-ENGINEERED na // PURPOSE OF THIS SUBROUTINE: // map data from surface domain to air domain for each particular zone - // METHODOLOGY EMPLOYED: - // na - - // REFERENCES: - // na - - // Using/Aliasing - using InternalHeatGains::SumAllInternalConvectionGains; - using InternalHeatGains::SumAllReturnAirConvectionGains; using Psychrometrics::PsyCpAirFnW; using Psychrometrics::PsyRhoAirFnPbTdbW; using Psychrometrics::PsyWFnTdpPb; - // Locals - Real64 CpAir; // specific heat - - // SUBROUTINE ARGUMENT DEFINITIONS: - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS: - // na - - // DERIVED TYPE DEFINITIONS: - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int SurfNum; // index for surfaces + Real64 CpAir; // specific heat int NodeNum; // index for air nodes Real64 SumSysMCp; // zone sum of air system MassFlowRate*Cp Real64 SumSysMCpT; // zone sum of air system MassFlowRate*Cp*T @@ -394,10 +369,11 @@ namespace MundtSimMgr { state.dataMundtSimMgr->ZoneAirDensity = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, - state.dataHeatBalFanSys->MAT(ZoneNum), - PsyWFnTdpPb(state, state.dataHeatBalFanSys->MAT(ZoneNum), state.dataEnvrn->OutBaroPress)); + state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT, + PsyWFnTdpPb(state, state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT, state.dataEnvrn->OutBaroPress)); ZoneMassFlowRate = state.dataLoopNodes->Node(ZoneNode).MassFlowRate; state.dataMundtSimMgr->SupplyAirVolumeRate = ZoneMassFlowRate / state.dataMundtSimMgr->ZoneAirDensity; + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); if (ZoneMassFlowRate <= 0.0001) { // system is off state.dataMundtSimMgr->QsysCoolTot = 0.0; @@ -408,7 +384,7 @@ namespace MundtSimMgr { for (NodeNum = 1; NodeNum <= state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).NumInletNodes; ++NodeNum) { NodeTemp = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).InletNode(NodeNum)).Temp; MassFlowRate = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).InletNode(NodeNum)).MassFlowRate; - CpAir = PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)); + CpAir = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat); SumSysMCp += MassFlowRate * CpAir; SumSysMCpT += MassFlowRate * CpAir * NodeTemp; } @@ -421,31 +397,31 @@ namespace MundtSimMgr { state.dataMundtSimMgr->SupplyAirTemp = SumSysMCpT / SumSysMCp; } // determine cooling load - CpAir = PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)); - state.dataMundtSimMgr->QsysCoolTot = -(SumSysMCpT - ZoneMassFlowRate * CpAir * state.dataHeatBalFanSys->MAT(ZoneNum)); + CpAir = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat); + state.dataMundtSimMgr->QsysCoolTot = + -(SumSysMCpT - ZoneMassFlowRate * CpAir * state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT); } // determine heat gains - state.dataMundtSimMgr->ConvIntGain = SumAllInternalConvectionGains(state, ZoneNum); + state.dataMundtSimMgr->ConvIntGain = InternalHeatGains::zoneSumAllInternalConvectionGains(state, ZoneNum); state.dataMundtSimMgr->ConvIntGain += state.dataHeatBalFanSys->SumConvHTRadSys(ZoneNum) + state.dataHeatBalFanSys->SumConvPool(ZoneNum) + - state.dataHeatBalFanSys->SysDepZoneLoadsLagged(ZoneNum) + - state.dataHeatBalFanSys->NonAirSystemResponse(ZoneNum) / ZoneMult; + thisZoneHB.SysDepZoneLoadsLagged + thisZoneHB.NonAirSystemResponse / ZoneMult; // Add heat to return air if zonal system (no return air) or cycling system (return air frequently very // low or zero) if (Zone(ZoneNum).NoHeatToReturnAir) { - RetAirConvGain = SumAllReturnAirConvectionGains(state, ZoneNum, 0); + RetAirConvGain = InternalHeatGains::zoneSumAllReturnAirConvectionGains(state, ZoneNum, 0); state.dataMundtSimMgr->ConvIntGain += RetAirConvGain; } state.dataMundtSimMgr->QventCool = - -state.dataHeatBalFanSys->MCPI(ZoneNum) * (Zone(ZoneNum).OutDryBulbTemp - state.dataHeatBalFanSys->MAT(ZoneNum)); + -thisZoneHB.MCPI * (Zone(ZoneNum).OutDryBulbTemp - state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT); // get surface data - for (SurfNum = 1; SurfNum <= state.dataMundtSimMgr->ZoneData(ZoneNum).NumOfSurfs; ++SurfNum) { + for (int SurfNum = 1; SurfNum <= state.dataMundtSimMgr->ZoneData(ZoneNum).NumOfSurfs; ++SurfNum) { state.dataMundtSimMgr->MundtAirSurf(SurfNum, state.dataMundtSimMgr->MundtZoneNum).Temp = - state.dataHeatBalSurf->SurfTempIn(state.dataMundtSimMgr->ZoneData(ZoneNum).SurfFirst + SurfNum - 1); + state.dataHeatBalSurf->SurfTempIn(state.dataMundtSimMgr->ZoneData(ZoneNum).HBsurfaceIndexes(SurfNum)); state.dataMundtSimMgr->MundtAirSurf(SurfNum, state.dataMundtSimMgr->MundtZoneNum).Hc = - state.dataHeatBalSurf->SurfHConvInt(state.dataMundtSimMgr->ZoneData(ZoneNum).SurfFirst + SurfNum - 1); + state.dataHeatBalSurf->SurfHConvInt(state.dataMundtSimMgr->ZoneData(ZoneNum).HBsurfaceIndexes(SurfNum)); } } @@ -758,15 +734,11 @@ namespace MundtSimMgr { // map data from air domain back to surface domain for each particular zone // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int SurfNum; // index for surfaces - int SurfFirst; // index number of the first surface in the zone - int NumOfSurfs; // number of surfaces in the zone int ZoneNodeNum; // index number of the zone node Real64 DeltaTemp; // dummy variable for temperature difference // get surface info - SurfFirst = state.dataMundtSimMgr->ZoneData(ZoneNum).SurfFirst; - NumOfSurfs = state.dataMundtSimMgr->ZoneData(ZoneNum).NumOfSurfs; + int NumOfSurfs = state.dataMundtSimMgr->ZoneData(ZoneNum).NumOfSurfs; if ((state.dataMundtSimMgr->SupplyAirVolumeRate > 0.0001) && (state.dataMundtSimMgr->QsysCoolTot > 0.0001)) { // Controlled zone when the system is on @@ -774,13 +746,13 @@ namespace MundtSimMgr { if (state.dataRoomAirMod->AirModel(ZoneNum).TempCoupleScheme == DataRoomAirModel::CouplingScheme::Direct) { // Use direct coupling scheme to report air temperatures back to surface/system domains // a) Bulk air temperatures -> TempEffBulkAir(SurfNum) - for (SurfNum = 1; SurfNum <= NumOfSurfs; ++SurfNum) { - state.dataHeatBal->SurfTempEffBulkAir(SurfFirst + SurfNum - 1) = + for (int SurfNum = 1; SurfNum <= NumOfSurfs; ++SurfNum) { + int hbSurfNum = state.dataMundtSimMgr->ZoneData(ZoneNum).HBsurfaceIndexes(SurfNum); + state.dataHeatBal->SurfTempEffBulkAir(hbSurfNum) = state.dataMundtSimMgr->MundtAirSurf(SurfNum, state.dataMundtSimMgr->MundtZoneNum).TMeanAir; // set flag for reference air temperature - state.dataSurface->SurfTAirRef(SurfFirst + SurfNum - 1) = DataSurfaces::RefAirTemp::AdjacentAirTemp; - state.dataSurface->SurfTAirRefRpt(SurfFirst + SurfNum - 1) = - DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(SurfFirst + SurfNum - 1)]; + state.dataSurface->SurfTAirRef(hbSurfNum) = DataSurfaces::RefAirTemp::AdjacentAirTemp; + state.dataSurface->SurfTAirRefRpt(hbSurfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(hbSurfNum)]; } // b) Average zone air temperature -> ZT(ZoneNum) // For Mundt model, average room air is the weighted value of floor and ceiling air temps @@ -796,15 +768,14 @@ namespace MundtSimMgr { } else { // Use indirect coupling scheme to report air temperatures back to surface/system domains // a) Bulk air temperatures -> TempEffBulkAir(SurfNum) - for (SurfNum = 1; SurfNum <= NumOfSurfs; ++SurfNum) { + for (int SurfNum = 1; SurfNum <= NumOfSurfs; ++SurfNum) { + int hbSurfNum = state.dataMundtSimMgr->ZoneData(ZoneNum).HBsurfaceIndexes(SurfNum); DeltaTemp = state.dataMundtSimMgr->MundtAirSurf(SurfNum, state.dataMundtSimMgr->MundtZoneNum).TMeanAir - state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->TstatNodeID, state.dataMundtSimMgr->MundtZoneNum).Temp; - state.dataHeatBal->SurfTempEffBulkAir(SurfFirst + SurfNum - 1) = - state.dataHeatBalFanSys->TempZoneThermostatSetPoint(ZoneNum) + DeltaTemp; + state.dataHeatBal->SurfTempEffBulkAir(hbSurfNum) = state.dataHeatBalFanSys->TempZoneThermostatSetPoint(ZoneNum) + DeltaTemp; // set flag for reference air temperature - state.dataSurface->SurfTAirRef(SurfFirst + SurfNum - 1) = DataSurfaces::RefAirTemp::AdjacentAirTemp; - state.dataSurface->SurfTAirRefRpt(SurfFirst + SurfNum - 1) = - DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(SurfFirst + SurfNum - 1)]; + state.dataSurface->SurfTAirRef(hbSurfNum) = DataSurfaces::RefAirTemp::AdjacentAirTemp; + state.dataSurface->SurfTAirRefRpt(hbSurfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(hbSurfNum)]; } // b) Average zone air temperature -> ZT(ZoneNum) // For Mundt model, average room air is the weighted value of floor and ceiling air temps @@ -817,19 +788,19 @@ namespace MundtSimMgr { state.dataMundtSimMgr->LineNode(state.dataMundtSimMgr->TstatNodeID, state.dataMundtSimMgr->MundtZoneNum).Temp; state.dataLoopNodes->Node(ZoneNodeNum).Temp = state.dataHeatBalFanSys->TempZoneThermostatSetPoint(ZoneNum) + DeltaTemp; // d) Thermostat air temperature -> TempTstatAir(ZoneNum) - state.dataHeatBalFanSys->TempTstatAir(ZoneNum) = - state.dataHeatBalFanSys->ZT(ZoneNum); // for indirect coupling, control air temp is equal to mean air temp? + state.dataHeatBalFanSys->TempTstatAir(ZoneNum) = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum) + .ZT; // for indirect coupling, control air temp is equal to mean air temp? } // set flag to indicate that Mundt model is used for this zone at the present time state.dataRoomAirMod->AirModel(ZoneNum).SimAirModel = true; } else { // Controlled zone when the system is off --> Use the mixing model instead of the Mundt model // Bulk air temperatures -> TempEffBulkAir(SurfNum) - for (SurfNum = 1; SurfNum <= NumOfSurfs; ++SurfNum) { - state.dataHeatBal->SurfTempEffBulkAir(SurfFirst + SurfNum - 1) = state.dataHeatBalFanSys->MAT(ZoneNum); + for (int SurfNum = 1; SurfNum <= NumOfSurfs; ++SurfNum) { + int hbSurfNum = state.dataMundtSimMgr->ZoneData(ZoneNum).HBsurfaceIndexes(SurfNum); + state.dataHeatBal->SurfTempEffBulkAir(hbSurfNum) = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; // set flag for reference air temperature - state.dataSurface->SurfTAirRef(SurfFirst + SurfNum - 1) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; - state.dataSurface->SurfTAirRefRpt(SurfFirst + SurfNum - 1) = - DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(SurfFirst + SurfNum - 1)]; + state.dataSurface->SurfTAirRef(hbSurfNum) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; + state.dataSurface->SurfTAirRefRpt(hbSurfNum) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(hbSurfNum)]; } // set flag to indicate that Mundt model is NOT used for this zone at the present time state.dataRoomAirMod->AirModel(ZoneNum).SimAirModel = false; diff --git a/src/EnergyPlus/MundtSimMgr.hh b/src/EnergyPlus/MundtSimMgr.hh index 2f3221d195e..1e57764f492 100644 --- a/src/EnergyPlus/MundtSimMgr.hh +++ b/src/EnergyPlus/MundtSimMgr.hh @@ -98,14 +98,9 @@ namespace MundtSimMgr { struct DefineZoneData { // Members - int SurfFirst; // index for first surface of the zone - int NumOfSurfs; // number of surfaces in the zone - int MundtZoneIndex; // index for zones using Mundt model - - // Default Constructor - DefineZoneData() : SurfFirst(0), NumOfSurfs(0), MundtZoneIndex(0) - { - } + int NumOfSurfs = 0; // number of surfaces in the zone + int MundtZoneIndex = 0; // index for zones using Mundt model + EPVector HBsurfaceIndexes; // list of surface indexes in this Mundt model zone }; // Functions diff --git a/src/EnergyPlus/OutdoorAirUnit.cc b/src/EnergyPlus/OutdoorAirUnit.cc index 5b511ce9c14..45af017f75d 100644 --- a/src/EnergyPlus/OutdoorAirUnit.cc +++ b/src/EnergyPlus/OutdoorAirUnit.cc @@ -59,7 +59,6 @@ #include #include #include -#include #include #include #include @@ -87,6 +86,7 @@ #include #include #include +#include namespace EnergyPlus { @@ -1800,10 +1800,10 @@ namespace OutdoorAirUnit { // Node condition if (OutAirUnit(OAUnitNum).ExtFan) { - state.dataLoopNodes->Node(InletNode).Temp = state.dataHeatBalFanSys->MAT(ZoneNum); + state.dataLoopNodes->Node(InletNode).Temp = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; state.dataLoopNodes->Node(SFanOutletNode).Temp = state.dataLoopNodes->Node(InletNode).Temp; } else { - state.dataLoopNodes->Node(SFanOutletNode).Temp = state.dataHeatBalFanSys->MAT(ZoneNum); + state.dataLoopNodes->Node(SFanOutletNode).Temp = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; } state.dataLoopNodes->Node(OutletNode).Temp = state.dataLoopNodes->Node(SFanOutletNode).Temp; @@ -1915,7 +1915,7 @@ namespace OutdoorAirUnit { // Control type check switch (UnitControlType) { case OAUnitCtrlType::Neutral: { - SetPointTemp = state.dataHeatBalFanSys->MAT(ZoneNum); + SetPointTemp = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; // Neutral Control Condition if (DesOATemp == SetPointTemp) { OutAirUnit(OAUnitNum).OperatingMode = Operation::NeutralMode; diff --git a/src/EnergyPlus/OutputReportTabular.cc b/src/EnergyPlus/OutputReportTabular.cc index 454e7d53744..51a68d2505e 100644 --- a/src/EnergyPlus/OutputReportTabular.cc +++ b/src/EnergyPlus/OutputReportTabular.cc @@ -15932,7 +15932,6 @@ void GetDelaySequences(EnergyPlusData &state, // static bool initAdjFenDone(false); moved to anonymous namespace for unit testing auto &ort(state.dataOutRptTab); - auto &Zone(state.dataHeatBal->Zone); if (!ort->initAdjFenDone) { state.dataOutRptTab->adjFenDone.allocate(state.dataEnvrn->TotDesDays + state.dataEnvrn->TotRunDesPersDays, @@ -15962,54 +15961,57 @@ void GetDelaySequences(EnergyPlusData &state, Real64 adjFeneSurfNetRadSeq = 0.0; // code from ComputeDelayedComponents starts - for (int jSurf = Zone(zoneIndex).HTSurfaceFirst; jSurf <= Zone(zoneIndex).HTSurfaceLast; ++jSurf) { - int radEnclosureNum = state.dataSurface->Surface(jSurf).RadEnclIndex; - - // for each time step, step back through time and apply decay curve to radiant heat for each end use absorbed in each surface - Real64 peopleConvFromSurf = 0.0; - Real64 equipConvFromSurf = 0.0; - Real64 hvacLossConvFromSurf = 0.0; - Real64 powerGenConvFromSurf = 0.0; - Real64 lightLWConvFromSurf = 0.0; - Real64 lightSWConvFromSurf = 0.0; - Real64 feneSolarConvFromSurf = 0.0; - - for (int mStepBack = 1; mStepBack <= kTimeStep; ++mStepBack) { - int sourceStep = kTimeStep - mStepBack + 1; - Real64 thisQRadThermInAbsMult = ort->TMULTseq(desDaySelected, sourceStep, radEnclosureNum) * - ort->ITABSFseq(desDaySelected, sourceStep, jSurf) * state.dataSurface->Surface(jSurf).Area * - decayCurve(mStepBack, jSurf); - peopleConvFromSurf += ort->peopleRadSeq(desDaySelected, sourceStep, zoneIndex) * thisQRadThermInAbsMult; - equipConvFromSurf += ort->equipRadSeq(desDaySelected, sourceStep, zoneIndex) * thisQRadThermInAbsMult; - hvacLossConvFromSurf += ort->hvacLossRadSeq(desDaySelected, sourceStep, zoneIndex) * thisQRadThermInAbsMult; - powerGenConvFromSurf += ort->powerGenRadSeq(desDaySelected, sourceStep, zoneIndex) * thisQRadThermInAbsMult; - lightLWConvFromSurf += ort->lightLWRadSeq(desDaySelected, sourceStep, zoneIndex) * thisQRadThermInAbsMult; - // short wave is already accumulated by surface - lightSWConvFromSurf += ort->lightSWRadSeq(desDaySelected, sourceStep, jSurf) * decayCurve(mStepBack, jSurf); - feneSolarConvFromSurf += ort->feneSolarRadSeq(desDaySelected, sourceStep, jSurf) * decayCurve(mStepBack, jSurf); - } // for mStepBack - - peopleConvIntoZone += peopleConvFromSurf; - equipConvIntoZone += equipConvFromSurf; - hvacLossConvIntoZone += hvacLossConvFromSurf; - powerGenConvIntoZone += powerGenConvFromSurf; - lightLWConvIntoZone += lightLWConvFromSurf; - lightSWConvIntoZone += lightSWConvFromSurf; - feneSolarConvIntoZone += feneSolarConvFromSurf; - // code from ComputeDelayedComponents ends - // determine the remaining convective heat from the surfaces that are not based - // on any of these other loads - // negative because heat from surface should be positive - surfDelaySeq(kTimeStep, jSurf) = - -ort->loadConvectedNormal(desDaySelected, kTimeStep, jSurf) - ort->netSurfRadSeq(desDaySelected, kTimeStep, jSurf) - - (peopleConvFromSurf + equipConvFromSurf + hvacLossConvFromSurf + powerGenConvFromSurf + lightLWConvFromSurf + - lightSWConvFromSurf + - feneSolarConvFromSurf); // remove net radiant for the surface - // also remove the net radiant component on the instanteous conduction for fenestration - if (state.dataSurface->Surface(jSurf).Class == DataSurfaces::SurfaceClass::Window) { - adjFeneSurfNetRadSeq += ort->netSurfRadSeq(desDaySelected, kTimeStep, jSurf); - } - } // for jSurf + for (int spaceNum : state.dataHeatBal->Zone(zoneIndex).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int jSurf = thisSpace.HTSurfaceFirst; jSurf <= thisSpace.HTSurfaceLast; ++jSurf) { + int radEnclosureNum = state.dataSurface->Surface(jSurf).RadEnclIndex; + + // for each time step, step back through time and apply decay curve to radiant heat for each end use absorbed in each surface + Real64 peopleConvFromSurf = 0.0; + Real64 equipConvFromSurf = 0.0; + Real64 hvacLossConvFromSurf = 0.0; + Real64 powerGenConvFromSurf = 0.0; + Real64 lightLWConvFromSurf = 0.0; + Real64 lightSWConvFromSurf = 0.0; + Real64 feneSolarConvFromSurf = 0.0; + + for (int mStepBack = 1; mStepBack <= kTimeStep; ++mStepBack) { + int sourceStep = kTimeStep - mStepBack + 1; + Real64 thisQRadThermInAbsMult = ort->TMULTseq(desDaySelected, sourceStep, radEnclosureNum) * + ort->ITABSFseq(desDaySelected, sourceStep, jSurf) * state.dataSurface->Surface(jSurf).Area * + decayCurve(mStepBack, jSurf); + peopleConvFromSurf += ort->peopleRadSeq(desDaySelected, sourceStep, zoneIndex) * thisQRadThermInAbsMult; + equipConvFromSurf += ort->equipRadSeq(desDaySelected, sourceStep, zoneIndex) * thisQRadThermInAbsMult; + hvacLossConvFromSurf += ort->hvacLossRadSeq(desDaySelected, sourceStep, zoneIndex) * thisQRadThermInAbsMult; + powerGenConvFromSurf += ort->powerGenRadSeq(desDaySelected, sourceStep, zoneIndex) * thisQRadThermInAbsMult; + lightLWConvFromSurf += ort->lightLWRadSeq(desDaySelected, sourceStep, zoneIndex) * thisQRadThermInAbsMult; + // short wave is already accumulated by surface + lightSWConvFromSurf += ort->lightSWRadSeq(desDaySelected, sourceStep, jSurf) * decayCurve(mStepBack, jSurf); + feneSolarConvFromSurf += ort->feneSolarRadSeq(desDaySelected, sourceStep, jSurf) * decayCurve(mStepBack, jSurf); + } // for mStepBack + + peopleConvIntoZone += peopleConvFromSurf; + equipConvIntoZone += equipConvFromSurf; + hvacLossConvIntoZone += hvacLossConvFromSurf; + powerGenConvIntoZone += powerGenConvFromSurf; + lightLWConvIntoZone += lightLWConvFromSurf; + lightSWConvIntoZone += lightSWConvFromSurf; + feneSolarConvIntoZone += feneSolarConvFromSurf; + // code from ComputeDelayedComponents ends + // determine the remaining convective heat from the surfaces that are not based + // on any of these other loads + // negative because heat from surface should be positive + surfDelaySeq(kTimeStep, jSurf) = + -ort->loadConvectedNormal(desDaySelected, kTimeStep, jSurf) - ort->netSurfRadSeq(desDaySelected, kTimeStep, jSurf) - + (peopleConvFromSurf + equipConvFromSurf + hvacLossConvFromSurf + powerGenConvFromSurf + lightLWConvFromSurf + + lightSWConvFromSurf + + feneSolarConvFromSurf); // remove net radiant for the surface + // also remove the net radiant component on the instanteous conduction for fenestration + if (state.dataSurface->Surface(jSurf).Class == DataSurfaces::SurfaceClass::Window) { + adjFeneSurfNetRadSeq += ort->netSurfRadSeq(desDaySelected, kTimeStep, jSurf); + } + } // for jSurf + } peopleDelaySeq(kTimeStep) = peopleConvIntoZone; equipDelaySeq(kTimeStep) = equipConvIntoZone; hvacLossDelaySeq(kTimeStep) = hvacLossConvIntoZone; @@ -16191,83 +16193,86 @@ void ComputeTableBodyUsingMovingAvg(EnergyPlusData &state, // opaque surfaces - must combine individual surfaces by class and other side conditions delayOpaque = 0.0; - for (int kSurf = state.dataHeatBal->Zone(zoneIndex).HTSurfaceFirst; kSurf <= state.dataHeatBal->Zone(zoneIndex).HTSurfaceLast; ++kSurf) { - - int curExtBoundCond = state.dataSurface->Surface(kSurf).ExtBoundCond; - // if exterior is other side coefficients using ground preprocessor terms then - // set it to ground instead of other side coefficients - if (curExtBoundCond == DataSurfaces::OtherSideCoefNoCalcExt || curExtBoundCond == DataSurfaces::OtherSideCoefCalcExt) { - if (has_prefixi(state.dataSurface->OSC(state.dataSurface->Surface(kSurf).OSCPtr).Name, "surfPropOthSdCoef")) { - curExtBoundCond = DataSurfaces::Ground; - } - } - AvgData = surfDelaySeq(_, kSurf); - General::MovingAvg(AvgData, state.dataSize->NumTimeStepsInAvg); - Real64 singleSurfDelay = AvgData(timeOfMax); - switch (state.dataSurface->Surface(kSurf).Class) { - case DataSurfaces::SurfaceClass::Wall: { - switch (curExtBoundCond) { - case DataSurfaces::ExternalEnvironment: { - delayOpaque(LoadCompRow::ExtWall) += singleSurfDelay; - } break; - case DataSurfaces::Ground: - case DataSurfaces::GroundFCfactorMethod: - case DataSurfaces::KivaFoundation: { - delayOpaque(LoadCompRow::GrdWall) += singleSurfDelay; - } break; - case DataSurfaces::OtherSideCoefNoCalcExt: - case DataSurfaces::OtherSideCoefCalcExt: - case DataSurfaces::OtherSideCondModeledExt: { - delayOpaque(LoadCompRow::OtherWall) += singleSurfDelay; - } break; - default: { // interzone - delayOpaque(LoadCompRow::IntZonWall) += singleSurfDelay; - } break; + for (int spaceNum : state.dataHeatBal->Zone(zoneIndex).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int kSurf = thisSpace.HTSurfaceFirst; kSurf <= thisSpace.HTSurfaceLast; ++kSurf) { + + int curExtBoundCond = state.dataSurface->Surface(kSurf).ExtBoundCond; + // if exterior is other side coefficients using ground preprocessor terms then + // set it to ground instead of other side coefficients + if (curExtBoundCond == DataSurfaces::OtherSideCoefNoCalcExt || curExtBoundCond == DataSurfaces::OtherSideCoefCalcExt) { + if (has_prefixi(state.dataSurface->OSC(state.dataSurface->Surface(kSurf).OSCPtr).Name, "surfPropOthSdCoef")) { + curExtBoundCond = DataSurfaces::Ground; + } } - } break; - case DataSurfaces::SurfaceClass::Floor: { - switch (curExtBoundCond) { - case DataSurfaces::ExternalEnvironment: { - delayOpaque(LoadCompRow::ExtFlr) += singleSurfDelay; - } break; - case DataSurfaces::Ground: - case DataSurfaces::GroundFCfactorMethod: - case DataSurfaces::KivaFoundation: { - delayOpaque(LoadCompRow::GrdFlr) += singleSurfDelay; - } break; - case DataSurfaces::OtherSideCoefNoCalcExt: - case DataSurfaces::OtherSideCoefCalcExt: - case DataSurfaces::OtherSideCondModeledExt: { - delayOpaque(LoadCompRow::OtherFlr) += singleSurfDelay; - } break; - default: { // interzone - delayOpaque(LoadCompRow::IntZonFlr) += singleSurfDelay; + AvgData = surfDelaySeq(_, kSurf); + General::MovingAvg(AvgData, state.dataSize->NumTimeStepsInAvg); + Real64 singleSurfDelay = AvgData(timeOfMax); + switch (state.dataSurface->Surface(kSurf).Class) { + case DataSurfaces::SurfaceClass::Wall: { + switch (curExtBoundCond) { + case DataSurfaces::ExternalEnvironment: { + delayOpaque(LoadCompRow::ExtWall) += singleSurfDelay; + } break; + case DataSurfaces::Ground: + case DataSurfaces::GroundFCfactorMethod: + case DataSurfaces::KivaFoundation: { + delayOpaque(LoadCompRow::GrdWall) += singleSurfDelay; + } break; + case DataSurfaces::OtherSideCoefNoCalcExt: + case DataSurfaces::OtherSideCoefCalcExt: + case DataSurfaces::OtherSideCondModeledExt: { + delayOpaque(LoadCompRow::OtherWall) += singleSurfDelay; + } break; + default: { // interzone + delayOpaque(LoadCompRow::IntZonWall) += singleSurfDelay; + } break; + } } break; - } - } break; - case DataSurfaces::SurfaceClass::Roof: { - switch (curExtBoundCond) { - case DataSurfaces::ExternalEnvironment: { - delayOpaque(LoadCompRow::Roof) += singleSurfDelay; + case DataSurfaces::SurfaceClass::Floor: { + switch (curExtBoundCond) { + case DataSurfaces::ExternalEnvironment: { + delayOpaque(LoadCompRow::ExtFlr) += singleSurfDelay; + } break; + case DataSurfaces::Ground: + case DataSurfaces::GroundFCfactorMethod: + case DataSurfaces::KivaFoundation: { + delayOpaque(LoadCompRow::GrdFlr) += singleSurfDelay; + } break; + case DataSurfaces::OtherSideCoefNoCalcExt: + case DataSurfaces::OtherSideCoefCalcExt: + case DataSurfaces::OtherSideCondModeledExt: { + delayOpaque(LoadCompRow::OtherFlr) += singleSurfDelay; + } break; + default: { // interzone + delayOpaque(LoadCompRow::IntZonFlr) += singleSurfDelay; + } break; + } } break; - case DataSurfaces::Ground: - case DataSurfaces::GroundFCfactorMethod: - case DataSurfaces::KivaFoundation: - case DataSurfaces::OtherSideCoefNoCalcExt: - case DataSurfaces::OtherSideCoefCalcExt: - case DataSurfaces::OtherSideCondModeledExt: { - delayOpaque(LoadCompRow::OtherRoof) += singleSurfDelay; + case DataSurfaces::SurfaceClass::Roof: { + switch (curExtBoundCond) { + case DataSurfaces::ExternalEnvironment: { + delayOpaque(LoadCompRow::Roof) += singleSurfDelay; + } break; + case DataSurfaces::Ground: + case DataSurfaces::GroundFCfactorMethod: + case DataSurfaces::KivaFoundation: + case DataSurfaces::OtherSideCoefNoCalcExt: + case DataSurfaces::OtherSideCoefCalcExt: + case DataSurfaces::OtherSideCondModeledExt: { + delayOpaque(LoadCompRow::OtherRoof) += singleSurfDelay; + } break; + default: { // interzone + delayOpaque(LoadCompRow::IntZonCeil) += singleSurfDelay; + } break; + } } break; - default: { // interzone - delayOpaque(LoadCompRow::IntZonCeil) += singleSurfDelay; + case DataSurfaces::SurfaceClass::Door: { + delayOpaque(LoadCompRow::OpqDoor) += singleSurfDelay; } break; + default: + break; } - } break; - case DataSurfaces::SurfaceClass::Door: { - delayOpaque(LoadCompRow::OpqDoor) += singleSurfDelay; - } break; - default: - break; } } for (int k = LoadCompRow::Roof; k <= LoadCompRow::OtherFlr; ++k) { diff --git a/src/EnergyPlus/PipeHeatTransfer.cc b/src/EnergyPlus/PipeHeatTransfer.cc index 6157551e048..a9f5cd3844c 100644 --- a/src/EnergyPlus/PipeHeatTransfer.cc +++ b/src/EnergyPlus/PipeHeatTransfer.cc @@ -61,7 +61,6 @@ #include #include #include -#include #include #include #include @@ -80,6 +79,7 @@ #include #include #include +#include namespace EnergyPlus::PipeHeatTransfer { @@ -1050,7 +1050,7 @@ void PipeHTData::InitPipesHeatTransfer(EnergyPlusData &state, bool const FirstHV state.dataPipeHT->nsvEnvironmentTemp = state.dataEnvrn->OutDryBulbTemp; } break; case EnvrnPtr::ZoneEnv: { - state.dataPipeHT->nsvEnvironmentTemp = state.dataHeatBalFanSys->MAT(this->EnvrZonePtr); + state.dataPipeHT->nsvEnvironmentTemp = state.dataZoneTempPredictorCorrector->zoneHeatBalance(this->EnvrZonePtr).MAT; } break; case EnvrnPtr::ScheduleEnv: { state.dataPipeHT->nsvEnvironmentTemp = GetCurrentScheduleValue(state, this->EnvrSchedPtr); @@ -1866,7 +1866,7 @@ Real64 PipeHTData::OutsidePipeHeatTransCoef(EnergyPlusData &state) AirVel = GetCurrentScheduleValue(state, this->EnvrVelSchedPtr); } break; case EnvrnPtr::ZoneEnv: { - AirTemp = state.dataHeatBalFanSys->MAT(this->EnvrZonePtr); + AirTemp = state.dataZoneTempPredictorCorrector->zoneHeatBalance(this->EnvrZonePtr).MAT; AirVel = RoomAirVel; } break; default: diff --git a/src/EnergyPlus/PlantPipingSystemsManager.cc b/src/EnergyPlus/PlantPipingSystemsManager.cc index d35b1f8d78b..777894a24fb 100644 --- a/src/EnergyPlus/PlantPipingSystemsManager.cc +++ b/src/EnergyPlus/PlantPipingSystemsManager.cc @@ -62,7 +62,6 @@ #include #include #include -#include #include #include #include @@ -80,6 +79,7 @@ #include #include #include +#include namespace EnergyPlus { @@ -288,7 +288,7 @@ namespace PlantPipingSystemsManager { // Set ZoneTemp equal to the average air temperature of the zones the coupled surfaces are part of. for (auto &z : thisDomain.ZoneCoupledSurfaces) { int ZoneNum = z.Zone; - ZoneTemp += state.dataHeatBalFanSys->ZTAV(ZoneNum); + ZoneTemp += state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZTAV; } ZoneTemp = ZoneTemp / thisDomain.ZoneCoupledSurfaces.size(); diff --git a/src/EnergyPlus/PurchasedAirManager.cc b/src/EnergyPlus/PurchasedAirManager.cc index a3e515f320b..cb778e74c94 100644 --- a/src/EnergyPlus/PurchasedAirManager.cc +++ b/src/EnergyPlus/PurchasedAirManager.cc @@ -81,6 +81,7 @@ #include #include #include +#include namespace EnergyPlus::PurchasedAirManager { @@ -2178,6 +2179,7 @@ void CalcPurchAirLoads(EnergyPlusData &state, // END IF if (UnitOn) { + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ControlledZoneNum); // Calculate current minimum outdoor air flow rate based on design OA specifications and DCV or CO2 control CalcPurchAirMinOAMassFlow(state, PurchAirNum, ControlledZoneNum, OAMassFlowRate); @@ -2246,7 +2248,7 @@ void CalcPurchAirLoads(EnergyPlusData &state, state.dataLoopNodes->Node(PurchAir(PurchAirNum).ZoneRecircAirNodeNum).Enthalpy))) { // Calculate supply MassFlowRate based on sensible load but limit to Max Cooling Supply Air Flow Rate if specified - CpAir = PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ControlledZoneNum)); + CpAir = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat); DeltaT = (state.dataLoopNodes->Node(OANodeNum).Temp - state.dataLoopNodes->Node(ZoneNodeNum).Temp); if (DeltaT < -SmallTempDiff) { SupplyMassFlowRate = QZnCoolSP / CpAir / DeltaT; @@ -2269,7 +2271,7 @@ void CalcPurchAirLoads(EnergyPlusData &state, // Mass flow rate to meet sensible load, at Minimum Cooling Supply Air Temperature SupplyMassFlowRateForCool = 0.0; if (CoolOn) { - CpAir = PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ControlledZoneNum)); + CpAir = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat); DeltaT = (PurchAir(PurchAirNum).MinCoolSuppAirTemp - state.dataLoopNodes->Node(ZoneNodeNum).Temp); if (DeltaT < -SmallTempDiff) { SupplyMassFlowRateForCool = QZnCoolSP / CpAir / DeltaT; @@ -2344,7 +2346,7 @@ void CalcPurchAirLoads(EnergyPlusData &state, // In general, in the cooling section, don't let SupplyTemp be set to something that results in heating if (SupplyMassFlowRate > 0.0) { // Calculate supply temp at SupplyMassFlowRate and recheck limit on Minimum Cooling Supply Air Temperature - CpAir = PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ControlledZoneNum)); + CpAir = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat); PurchAir(PurchAirNum).SupplyTemp = QZnCoolSP / (CpAir * SupplyMassFlowRate) + state.dataLoopNodes->Node(ZoneNodeNum).Temp; PurchAir(PurchAirNum).SupplyTemp = max(PurchAir(PurchAirNum).SupplyTemp, PurchAir(PurchAirNum).MinCoolSuppAirTemp); // This is the cooling mode, so SupplyTemp can't be more than MixedAirTemp @@ -2558,7 +2560,7 @@ void CalcPurchAirLoads(EnergyPlusData &state, // Mass flow rate to meet sensible load, at Minimum Cooling Supply Air Temperature SupplyMassFlowRateForHeat = 0.0; if ((HeatOn) && (OperatingMode == OpMode::Heat)) { - CpAir = PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ControlledZoneNum)); + CpAir = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat); DeltaT = (PurchAir(PurchAirNum).MaxHeatSuppAirTemp - state.dataLoopNodes->Node(ZoneNodeNum).Temp); if (DeltaT > SmallTempDiff) { SupplyMassFlowRateForHeat = QZnHeatSP / CpAir / DeltaT; @@ -2634,7 +2636,7 @@ void CalcPurchAirLoads(EnergyPlusData &state, if (SupplyMassFlowRate > 0.0) { if ((HeatOn) && (OperatingMode == OpMode::Heat)) { // Calculate supply temp at SupplyMassFlowRate and check limit on Maximum Heating Supply Air Temperature - CpAir = PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ControlledZoneNum)); + CpAir = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat); PurchAir(PurchAirNum).SupplyTemp = QZnHeatSP / (CpAir * SupplyMassFlowRate) + state.dataLoopNodes->Node(ZoneNodeNum).Temp; PurchAir(PurchAirNum).SupplyTemp = min(PurchAir(PurchAirNum).SupplyTemp, PurchAir(PurchAirNum).MaxHeatSuppAirTemp); // This is the heating mode, so SupplyTemp can't be less than MixedAirTemp @@ -2822,7 +2824,7 @@ void CalcPurchAirLoads(EnergyPlusData &state, SupplyEnthalpy = PsyHFnTdbW(PurchAir(PurchAirNum).SupplyTemp, PurchAir(PurchAirNum).SupplyHumRat); - CpAir = PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ControlledZoneNum)); + CpAir = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat); 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 @@ -2831,7 +2833,7 @@ void CalcPurchAirLoads(EnergyPlusData &state, PurchAir(PurchAirNum).LatOutputToZone = SupplyMassFlowRate * (SupplyEnthalpy - state.dataLoopNodes->Node(ZoneNodeNum).Enthalpy) - PurchAir(PurchAirNum).SenOutputToZone; - CpAir = PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ControlledZoneNum)); + CpAir = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat); if (PurchAir(PurchAirNum).OutdoorAir) { PurchAir(PurchAirNum).OASenOutput = OAMassFlowRate * CpAir * (state.dataLoopNodes->Node(OANodeNum).Temp - state.dataLoopNodes->Node(ZoneNodeNum).Temp); diff --git a/src/EnergyPlus/RoomAirModelAirflowNetwork.cc b/src/EnergyPlus/RoomAirModelAirflowNetwork.cc index d38bbdef653..3b4bc81424f 100644 --- a/src/EnergyPlus/RoomAirModelAirflowNetwork.cc +++ b/src/EnergyPlus/RoomAirModelAirflowNetwork.cc @@ -58,7 +58,6 @@ #include #include #include -#include #include #include #include @@ -88,6 +87,7 @@ #include #include #include +#include namespace EnergyPlus { @@ -251,7 +251,6 @@ namespace RoomAirModelAirflowNetwork { Real64 SumLinkM; Real64 SumLinkMW; int LoopZone; - int NumSurfs; int LoopAirNode; int NodeNum; int NodeIn; @@ -273,7 +272,12 @@ namespace RoomAirModelAirflowNetwork { // loop over all zones with RoomAirflowNetwork model for (LoopZone = 1; LoopZone <= state.dataGlobal->NumOfZones; ++LoopZone) { if (!state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(LoopZone).IsUsed) continue; - NumSurfs = state.dataHeatBal->Zone(LoopZone).HTSurfaceLast - state.dataHeatBal->Zone(LoopZone).HTSurfaceFirst + 1; + int NumSurfs = 0; + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + NumSurfs += thisSpace.HTSurfaceLast - thisSpace.HTSurfaceFirst + 1; + } + for (LoopAirNode = 1; LoopAirNode <= state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(LoopZone).NumOfAirNodes; ++LoopAirNode) { // loop over all the modeled room air nodes // calculate volume of air in node's control volume @@ -875,7 +879,6 @@ namespace RoomAirModelAirflowNetwork { bool ZoneRetPlenumAirFlag; bool ZoneSupPlenumAirFlag; Real64 CpAir; // Specific heat of air - int SurfNum; // Surface number Real64 HA; // !Hc*Area Real64 Area; // !Effective surface area Real64 RefAirTemp; // !Reference air temperature for surface convection calculations @@ -958,6 +961,7 @@ namespace RoomAirModelAirflowNetwork { } // ZoneSupPlenumNum // Plenum and controlled zones have a different set of inlet nodes which must be calculated. + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); if (ControlledZoneAirFlag) { auto &thisZoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(ZoneNum); for (NodeNum = 1; NodeNum <= thisZoneEquipConfig.NumInletNodes; ++NodeNum) { @@ -972,7 +976,7 @@ namespace RoomAirModelAirflowNetwork { NodeW = state.dataLoopNodes->Node(thisZoneEquipConfig.InletNode(NodeNum)).HumRat; MassFlowRate = state.dataLoopNodes->Node(thisZoneEquipConfig.InletNode(NodeNum)).MassFlowRate * state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(RoomAirNodeNum).HVAC(EquipLoop).SupplyFraction; - CpAir = PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)); + CpAir = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat); SumSysMCp += MassFlowRate * CpAir; SumSysMCpT += MassFlowRate * CpAir * NodeTemp; SumSysM += MassFlowRate; @@ -985,7 +989,7 @@ namespace RoomAirModelAirflowNetwork { // Get node conditions NodeTemp = state.dataLoopNodes->Node(state.dataZonePlenum->ZoneRetPlenCond(ZoneRetPlenumNum).InletNode(NodeNum)).Temp; MassFlowRate = state.dataLoopNodes->Node(state.dataZonePlenum->ZoneRetPlenCond(ZoneRetPlenumNum).InletNode(NodeNum)).MassFlowRate; - CpAir = PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)); + CpAir = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat); SumSysMCp += MassFlowRate * CpAir; SumSysMCpT += MassFlowRate * CpAir * NodeTemp; } // NodeNum @@ -996,7 +1000,7 @@ namespace RoomAirModelAirflowNetwork { ADUInNode = state.dataDefineEquipment->AirDistUnit(ADUNum).InletNodeNum; NodeTemp = state.dataLoopNodes->Node(ADUInNode).Temp; MassFlowRate = state.dataDefineEquipment->AirDistUnit(ADUNum).MassFlowRateUpStrLk; - CpAir = PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)); + CpAir = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat); SumSysMCp += MassFlowRate * CpAir; SumSysMCpT += MassFlowRate * CpAir * NodeTemp; } @@ -1004,7 +1008,7 @@ namespace RoomAirModelAirflowNetwork { ADUOutNode = state.dataDefineEquipment->AirDistUnit(ADUNum).OutletNodeNum; NodeTemp = state.dataLoopNodes->Node(ADUOutNode).Temp; MassFlowRate = state.dataDefineEquipment->AirDistUnit(ADUNum).MassFlowRateDnStrLk; - CpAir = PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)); + CpAir = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat); SumSysMCp += MassFlowRate * CpAir; SumSysMCpT += MassFlowRate * CpAir * NodeTemp; } @@ -1013,7 +1017,7 @@ namespace RoomAirModelAirflowNetwork { // Get node conditions NodeTemp = state.dataLoopNodes->Node(state.dataZonePlenum->ZoneSupPlenCond(ZoneSupPlenumNum).InletNode).Temp; MassFlowRate = state.dataLoopNodes->Node(state.dataZonePlenum->ZoneSupPlenCond(ZoneSupPlenumNum).InletNode).MassFlowRate; - CpAir = PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)); + CpAir = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat); SumSysMCp += MassFlowRate * CpAir; SumSysMCpT += MassFlowRate * CpAir * NodeTemp; } @@ -1029,111 +1033,111 @@ namespace RoomAirModelAirflowNetwork { // Modified by Gu to include assigned surfaces only shown in the surface lsit if (!state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(RoomAirNodeNum).HasSurfacesAssigned) return; - for (SurfNum = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst; SurfNum <= state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast; ++SurfNum) { - - if (state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).ControlAirNodeID == RoomAirNodeNum) { - Found = false; - for (Loop = 1; Loop <= state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).NumOfAirNodes; ++Loop) { - if (Loop != RoomAirNodeNum) { - if (state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(Loop).SurfMask( - SurfNum - state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst + 1)) { - Found = true; - break; + int surfCount = 0; + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { + ++surfCount; + if (state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).ControlAirNodeID == RoomAirNodeNum) { + Found = false; + for (Loop = 1; Loop <= state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).NumOfAirNodes; ++Loop) { + if (Loop != RoomAirNodeNum) { + if (state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(Loop).SurfMask(surfCount)) { + Found = true; + break; + } } } + if (Found) continue; + } else { + if (!state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(RoomAirNodeNum).SurfMask(surfCount)) continue; } - if (Found) continue; - } else { - if (!state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum) - .Node(RoomAirNodeNum) - .SurfMask(SurfNum - state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst + 1)) - continue; - } - HA = 0.0; - Area = state.dataSurface->Surface(SurfNum).Area; // For windows, this is the glazing area + HA = 0.0; + Area = state.dataSurface->Surface(SurfNum).Area; // For windows, this is the glazing area - if (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window) { + if (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window) { - // Add to the convective internal gains - if (ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum))) { - // The shade area covers the area of the glazing plus the area of the dividers. - Area += state.dataSurface->SurfWinDividerArea(SurfNum); - SumIntGain += state.dataSurface->SurfWinDividerHeatGain(SurfNum); - } + // Add to the convective internal gains + if (ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum))) { + // The shade area covers the area of the glazing plus the area of the dividers. + Area += state.dataSurface->SurfWinDividerArea(SurfNum); + SumIntGain += state.dataSurface->SurfWinDividerHeatGain(SurfNum); + } - // Convective heat gain from natural convection in gap between glass and interior shade or blind - if (ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum))) - SumIntGain += state.dataSurface->SurfWinConvHeatFlowNatural(SurfNum); - - // Convective heat gain from airflow window - if (state.dataSurface->SurfWinAirflowThisTS(SurfNum) > 0.0) { - SumIntGain += state.dataSurface->SurfWinConvHeatGainToZoneAir(SurfNum); - if (state.dataHeatBal->Zone(ZoneNum).NoHeatToReturnAir) { - SumIntGain += state.dataSurface->SurfWinRetHeatGainToZoneAir(SurfNum); - state.dataSurface->SurfWinHeatGain(SurfNum) += state.dataSurface->SurfWinRetHeatGainToZoneAir(SurfNum); - if (state.dataSurface->SurfWinHeatGain(SurfNum) >= 0.0) { - state.dataSurface->SurfWinHeatGainRep(SurfNum) = state.dataSurface->SurfWinHeatGain(SurfNum); - state.dataSurface->SurfWinHeatGainRepEnergy(SurfNum) = - state.dataSurface->SurfWinHeatGainRep(SurfNum) * state.dataGlobal->TimeStepZone * DataGlobalConstants::SecInHour; - } else { - state.dataSurface->SurfWinHeatLossRep(SurfNum) = -state.dataSurface->SurfWinHeatGain(SurfNum); - state.dataSurface->SurfWinHeatLossRepEnergy(SurfNum) = - state.dataSurface->SurfWinHeatLossRep(SurfNum) * state.dataGlobal->TimeStepZone * DataGlobalConstants::SecInHour; + // Convective heat gain from natural convection in gap between glass and interior shade or blind + if (ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum))) + SumIntGain += state.dataSurface->SurfWinConvHeatFlowNatural(SurfNum); + + // Convective heat gain from airflow window + if (state.dataSurface->SurfWinAirflowThisTS(SurfNum) > 0.0) { + SumIntGain += state.dataSurface->SurfWinConvHeatGainToZoneAir(SurfNum); + if (state.dataHeatBal->Zone(ZoneNum).NoHeatToReturnAir) { + SumIntGain += state.dataSurface->SurfWinRetHeatGainToZoneAir(SurfNum); + state.dataSurface->SurfWinHeatGain(SurfNum) += state.dataSurface->SurfWinRetHeatGainToZoneAir(SurfNum); + if (state.dataSurface->SurfWinHeatGain(SurfNum) >= 0.0) { + state.dataSurface->SurfWinHeatGainRep(SurfNum) = state.dataSurface->SurfWinHeatGain(SurfNum); + state.dataSurface->SurfWinHeatGainRepEnergy(SurfNum) = + state.dataSurface->SurfWinHeatGainRep(SurfNum) * state.dataGlobal->TimeStepZone * DataGlobalConstants::SecInHour; + } else { + state.dataSurface->SurfWinHeatLossRep(SurfNum) = -state.dataSurface->SurfWinHeatGain(SurfNum); + state.dataSurface->SurfWinHeatLossRepEnergy(SurfNum) = + state.dataSurface->SurfWinHeatLossRep(SurfNum) * state.dataGlobal->TimeStepZone * DataGlobalConstants::SecInHour; + } + state.dataSurface->SurfWinHeatTransferRepEnergy(SurfNum) = + state.dataSurface->SurfWinHeatGain(SurfNum) * state.dataGlobal->TimeStepZone * DataGlobalConstants::SecInHour; } - state.dataSurface->SurfWinHeatTransferRepEnergy(SurfNum) = - state.dataSurface->SurfWinHeatGain(SurfNum) * state.dataGlobal->TimeStepZone * DataGlobalConstants::SecInHour; } - } - // Add to the surface convection sums - if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) { - // Window frame contribution - SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinFrameArea(SurfNum) * - (1.0 + state.dataSurface->SurfWinProjCorrFrIn(SurfNum)) * state.dataSurface->SurfWinFrameTempIn(SurfNum); - HA += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinFrameArea(SurfNum) * - (1.0 + state.dataSurface->SurfWinProjCorrFrIn(SurfNum)); - } + // Add to the surface convection sums + if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) { + // Window frame contribution + SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinFrameArea(SurfNum) * + (1.0 + state.dataSurface->SurfWinProjCorrFrIn(SurfNum)) * state.dataSurface->SurfWinFrameTempIn(SurfNum); + HA += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinFrameArea(SurfNum) * + (1.0 + state.dataSurface->SurfWinProjCorrFrIn(SurfNum)); + } - if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0 && - !ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum))) { - // Window divider contribution(only from shade or blind for window with divider and interior shade or blind) - SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinDividerArea(SurfNum) * - (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) * state.dataSurface->SurfWinDividerTempIn(SurfNum); - HA += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinDividerArea(SurfNum) * - (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivIn(SurfNum)); - } + if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0 && + !ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum))) { + // Window divider contribution(only from shade or blind for window with divider and interior shade or blind) + SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinDividerArea(SurfNum) * + (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) * + state.dataSurface->SurfWinDividerTempIn(SurfNum); + HA += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinDividerArea(SurfNum) * + (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivIn(SurfNum)); + } - } // End of check if window - - HA = HA + state.dataHeatBalSurf->SurfHConvInt(SurfNum) * Area; - SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * Area * state.dataHeatBalSurf->SurfTempInTmp(SurfNum); - - if (state.dataSurface->SurfTAirRef(SurfNum) == DataSurfaces::RefAirTemp::ZoneMeanAirTemp) { - // The zone air is the reference temperature(which is to be solved for in CorrectZoneAirTemp). - RefAirTemp = state.dataHeatBalFanSys->MAT(ZoneNum); - SumHA += HA; - } else if (state.dataSurface->SurfTAirRef(SurfNum) == DataSurfaces::RefAirTemp::AdjacentAirTemp) { - RefAirTemp = state.dataHeatBal->SurfTempEffBulkAir(SurfNum); - SumHATref += HA * RefAirTemp; - } else if (state.dataSurface->SurfTAirRef(SurfNum) == DataSurfaces::RefAirTemp::ZoneSupplyAirTemp) { - // check whether this zone is a controlled zone or not - if (!ControlledZoneAirFlag) { - ShowFatalError(state, - "Zones must be controlled for Ceiling-Diffuser Convection model. No system serves zone " + - state.dataHeatBal->Zone(ZoneNum).Name); - return; + } // End of check if window + + HA = HA + state.dataHeatBalSurf->SurfHConvInt(SurfNum) * Area; + SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * Area * state.dataHeatBalSurf->SurfTempInTmp(SurfNum); + + if (state.dataSurface->SurfTAirRef(SurfNum) == DataSurfaces::RefAirTemp::ZoneMeanAirTemp) { + // The zone air is the reference temperature(which is to be solved for in CorrectZoneAirTemp). + RefAirTemp = thisZoneHB.MAT; + SumHA += HA; + } else if (state.dataSurface->SurfTAirRef(SurfNum) == DataSurfaces::RefAirTemp::AdjacentAirTemp) { + RefAirTemp = state.dataHeatBal->SurfTempEffBulkAir(SurfNum); + SumHATref += HA * RefAirTemp; + } else if (state.dataSurface->SurfTAirRef(SurfNum) == DataSurfaces::RefAirTemp::ZoneSupplyAirTemp) { + // check whether this zone is a controlled zone or not + if (!ControlledZoneAirFlag) { + ShowFatalError(state, + "Zones must be controlled for Ceiling-Diffuser Convection model. No system serves zone " + + state.dataHeatBal->Zone(ZoneNum).Name); + return; + } + // determine supply air temperature as a weighted average of the inlet temperatures. + RefAirTemp = SumSysMCpT / SumSysMCp; + SumHATref += HA * RefAirTemp; + } else { + RefAirTemp = thisZoneHB.MAT; + SumHA = SumHA + HA; } - // determine supply air temperature as a weighted average of the inlet temperatures. - RefAirTemp = SumSysMCpT / SumSysMCp; - SumHATref += HA * RefAirTemp; - } else { - RefAirTemp = state.dataHeatBalFanSys->MAT(ZoneNum); - SumHA = SumHA + HA; - } - - } // SurfNum + } // SurfNum + } // Assemble values state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(RoomAirNodeNum).SumHA = SumHA; state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(RoomAirNodeNum).SumHATsurf = SumHATsurf; @@ -1173,7 +1177,6 @@ namespace RoomAirModelAirflowNetwork { using Psychrometrics::PsyWFnTdbRhPb; // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int SurfNum; int Loop; Real64 RhoAirZone; Real64 Wsurf; @@ -1183,72 +1186,76 @@ namespace RoomAirModelAirflowNetwork { SumHmARa = 0.0; SumHmARaW = 0.0; - for (SurfNum = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst; SurfNum <= state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast; ++SurfNum) { - if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Window) continue; - - if (state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).ControlAirNodeID == RoomAirNode) { - Found = false; - for (Loop = 1; Loop <= state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).NumOfAirNodes; ++Loop) { - // None - assigned surfaces belong to the zone node - if (Loop != RoomAirNode) { - if (state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(Loop).SurfMask( - SurfNum - state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst + 1)) { - Found = true; - break; + int surfCount = 0; + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { + ++surfCount; + if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Window) continue; + + if (state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).ControlAirNodeID == RoomAirNode) { + Found = false; + for (Loop = 1; Loop <= state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).NumOfAirNodes; ++Loop) { + // None - assigned surfaces belong to the zone node + if (Loop != RoomAirNode) { + if (state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(Loop).SurfMask(surfCount)) { + Found = true; + break; + } } } + if (Found) continue; + } else { + if (!state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(RoomAirNode).SurfMask(surfCount)) continue; } - if (Found) continue; - } else { - if (!state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum) - .Node(RoomAirNode) - .SurfMask(SurfNum - state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst + 1)) - continue; - } - auto &HMassConvInFD = state.dataMstBal->HMassConvInFD; - auto &RhoVaporSurfIn = state.dataMstBal->RhoVaporSurfIn; - auto &RhoVaporAirIn = state.dataMstBal->RhoVaporAirIn; - if (state.dataSurface->Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { - UpdateHeatBalHAMT(state, SurfNum); + auto &HMassConvInFD = state.dataMstBal->HMassConvInFD; + auto &RhoVaporSurfIn = state.dataMstBal->RhoVaporSurfIn; + auto &RhoVaporAirIn = state.dataMstBal->RhoVaporAirIn; + if (state.dataSurface->Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::HAMT) { + UpdateHeatBalHAMT(state, SurfNum); - SumHmAW += HMassConvInFD(SurfNum) * state.dataSurface->Surface(SurfNum).Area * (RhoVaporSurfIn(SurfNum) - RhoVaporAirIn(SurfNum)); + SumHmAW += HMassConvInFD(SurfNum) * state.dataSurface->Surface(SurfNum).Area * (RhoVaporSurfIn(SurfNum) - RhoVaporAirIn(SurfNum)); - RhoAirZone = PsyRhoAirFnPbTdbW( - state, - state.dataEnvrn->OutBaroPress, - state.dataHeatBalFanSys->MAT(state.dataSurface->Surface(SurfNum).Zone), - PsyRhFnTdbRhov( - state, state.dataHeatBalFanSys->MAT(state.dataSurface->Surface(SurfNum).Zone), RhoVaporAirIn(SurfNum), "RhoAirZone")); + RhoAirZone = PsyRhoAirFnPbTdbW( + state, + state.dataEnvrn->OutBaroPress, + state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataSurface->Surface(SurfNum).Zone).MAT, + PsyRhFnTdbRhov(state, + state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataSurface->Surface(SurfNum).Zone).MAT, + RhoVaporAirIn(SurfNum), + "RhoAirZone")); - Wsurf = PsyWFnTdbRhPb(state, - state.dataHeatBalSurf->SurfTempInTmp(SurfNum), - PsyRhFnTdbRhov(state, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), RhoVaporSurfIn(SurfNum), "Wsurf"), - state.dataEnvrn->OutBaroPress); + Wsurf = PsyWFnTdbRhPb(state, + state.dataHeatBalSurf->SurfTempInTmp(SurfNum), + PsyRhFnTdbRhov(state, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), RhoVaporSurfIn(SurfNum), "Wsurf"), + state.dataEnvrn->OutBaroPress); - SumHmARa = SumHmARa + HMassConvInFD(SurfNum) * state.dataSurface->Surface(SurfNum).Area * RhoAirZone; + SumHmARa = SumHmARa + HMassConvInFD(SurfNum) * state.dataSurface->Surface(SurfNum).Area * RhoAirZone; - SumHmARaW = SumHmARaW + HMassConvInFD(SurfNum) * state.dataSurface->Surface(SurfNum).Area * RhoAirZone * Wsurf; - } + SumHmARaW = SumHmARaW + HMassConvInFD(SurfNum) * state.dataSurface->Surface(SurfNum).Area * RhoAirZone * Wsurf; + } + + if (state.dataSurface->Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) { - if (state.dataSurface->Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::EMPD) { - - UpdateMoistureBalanceEMPD(state, SurfNum); - RhoVaporSurfIn(SurfNum) = state.dataMstBalEMPD->RVSurface(SurfNum); - - SumHmAW = - SumHmAW + HMassConvInFD(SurfNum) * state.dataSurface->Surface(SurfNum).Area * (RhoVaporSurfIn(SurfNum) - RhoVaporAirIn(SurfNum)); - SumHmARa = SumHmARa + - HMassConvInFD(SurfNum) * state.dataSurface->Surface(SurfNum).Area * - PsyRhoAirFnPbTdbW( - state, - state.dataEnvrn->OutBaroPress, - state.dataHeatBalSurf->SurfTempInTmp(SurfNum), - PsyWFnTdbRhPb(state, - state.dataHeatBalSurf->SurfTempInTmp(SurfNum), - PsyRhFnTdbRhovLBnd0C(state, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), RhoVaporAirIn(SurfNum)), - state.dataEnvrn->OutBaroPress)); - SumHmARaW = SumHmARaW + HMassConvInFD(SurfNum) * state.dataSurface->Surface(SurfNum).Area * RhoVaporSurfIn(SurfNum); + UpdateMoistureBalanceEMPD(state, SurfNum); + RhoVaporSurfIn(SurfNum) = state.dataMstBalEMPD->RVSurface(SurfNum); + + SumHmAW = SumHmAW + + HMassConvInFD(SurfNum) * state.dataSurface->Surface(SurfNum).Area * (RhoVaporSurfIn(SurfNum) - RhoVaporAirIn(SurfNum)); + SumHmARa = + SumHmARa + + HMassConvInFD(SurfNum) * state.dataSurface->Surface(SurfNum).Area * + PsyRhoAirFnPbTdbW( + state, + state.dataEnvrn->OutBaroPress, + state.dataHeatBalSurf->SurfTempInTmp(SurfNum), + PsyWFnTdbRhPb(state, + state.dataHeatBalSurf->SurfTempInTmp(SurfNum), + PsyRhFnTdbRhovLBnd0C(state, state.dataHeatBalSurf->SurfTempInTmp(SurfNum), RhoVaporAirIn(SurfNum)), + state.dataEnvrn->OutBaroPress)); + SumHmARaW = SumHmARaW + HMassConvInFD(SurfNum) * state.dataSurface->Surface(SurfNum).Area * RhoVaporSurfIn(SurfNum); + } } } diff --git a/src/EnergyPlus/RoomAirModelManager.cc b/src/EnergyPlus/RoomAirModelManager.cc index fceeba232e3..4ea0648f177 100644 --- a/src/EnergyPlus/RoomAirModelManager.cc +++ b/src/EnergyPlus/RoomAirModelManager.cc @@ -85,6 +85,7 @@ #include #include #include +#include namespace EnergyPlus { @@ -103,7 +104,7 @@ namespace RoomAirModelManager { // Using/Aliasing using namespace DataRoomAirModel; - void ManageAirModel(EnergyPlusData &state, int &ZoneNum) + void ManageAirModel(EnergyPlusData &state, int const ZoneNum) { // SUBROUTINE INFORMATION: @@ -121,6 +122,8 @@ namespace RoomAirModelManager { state.dataRoomAirModelMgr->GetAirModelData = false; } + if (!state.dataRoomAirMod->anyNonMixingRoomAirModel) return; + if (state.dataRoomAirMod->UCSDModelUsed) { SharedDVCVUFDataInit(state, ZoneNum); } @@ -245,7 +248,6 @@ namespace RoomAirModelManager { int Status; // Notes if there was an error in processing the input int thisSurfinZone; // working variable for indexing surfaces within a ZoneRadiantInfo structure - int thisHBsurfID; // working variable for indexing surfaces in main Surface structure int thisPattern; int i; // do loop indexer @@ -340,24 +342,30 @@ namespace RoomAirModelManager { state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).ZoneID = ZoneNum; // figure number of surfaces for this zone - state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).totNumSurfs = - state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast - state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst + 1; + state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).totNumSurfs = 0; + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).totNumSurfs += thisSpace.HTSurfaceLast - thisSpace.HTSurfaceFirst + 1; + } // allocate nested derived type for surface info state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).Surf.allocate(state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).totNumSurfs); // Fill in what we know for nested structure for surfaces - for (thisSurfinZone = 1; thisSurfinZone <= state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).totNumSurfs; ++thisSurfinZone) { - thisHBsurfID = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst + thisSurfinZone - 1; - if (state.dataSurface->Surface(thisHBsurfID).Class == DataSurfaces::SurfaceClass::IntMass) { - state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).Surf(thisSurfinZone).SurfID = thisHBsurfID; - state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).Surf(thisSurfinZone).Zeta = 0.5; - continue; - } - - state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).Surf(thisSurfinZone).SurfID = thisHBsurfID; + thisSurfinZone = 0; + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int thisHBsurfID = thisSpace.HTSurfaceFirst; thisHBsurfID <= thisSpace.HTSurfaceLast; ++thisHBsurfID) { + ++thisSurfinZone; + if (state.dataSurface->Surface(thisHBsurfID).Class == DataSurfaces::SurfaceClass::IntMass) { + state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).Surf(thisSurfinZone).SurfID = thisHBsurfID; + state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).Surf(thisSurfinZone).Zeta = 0.5; + continue; + } - state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).Surf(thisSurfinZone).Zeta = FigureNDheightInZone(state, thisHBsurfID); + state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).Surf(thisSurfinZone).SurfID = thisHBsurfID; + state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).Surf(thisSurfinZone).Zeta = FigureNDheightInZone(state, thisHBsurfID); + } } // loop through surfaces in this zone } // loop through number of 'RoomAir:TemperaturePattern:UserDefined' objects @@ -660,10 +668,7 @@ namespace RoomAirModelManager { int NumSurfsInvolved; // Number of surfaces involved with air nodes int SurfCount; // Number of surfaces involved with air nodes // (used for checking error) - int SurfNum; // Index number for surfaces - int SurfFirst; // Index number for first surface of zones - int NumOfSurfs; // Index number for last surface of zones - int ListSurfNum; // Index number of surfaces listed in the air node object + int NumOfSurfs; // Index number for last surface of zones bool SurfNeeded; if (!state.dataRoomAirMod->MundtModelUsed) return; @@ -715,7 +720,11 @@ namespace RoomAirModelManager { ErrorsFound = true; } else { ZoneNum = state.dataRoomAirMod->AirNode(AirNodeNum).ZonePtr; - NumOfSurfs = state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast - state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst + 1; + NumOfSurfs = 0; + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + NumOfSurfs += thisSpace.HTSurfaceLast - thisSpace.HTSurfaceFirst + 1; + } state.dataRoomAirMod->AirNode(AirNodeNum).SurfMask.allocate(NumOfSurfs); } @@ -790,8 +799,11 @@ namespace RoomAirModelManager { // this air node is in this zone; hence, first get name of all surfaces in this zone ZoneNum = state.dataRoomAirMod->AirNode(AirNodeNum).ZonePtr; - SurfFirst = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst; - NumOfSurfs = state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast - state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst + 1; + NumOfSurfs = 0; + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + NumOfSurfs += thisSpace.HTSurfaceLast - thisSpace.HTSurfaceFirst + 1; + } // terminate the program due to a severe error in the specified input if ((NumSurfsInvolved) > NumOfSurfs) { @@ -804,13 +816,22 @@ namespace RoomAirModelManager { // relate surfaces to this air node and check to see whether surface names are specified correctly or not SurfCount = 0; - --SurfFirst; - for (ListSurfNum = 4; ListSurfNum <= NumAlphas; ++ListSurfNum) { - for (SurfNum = 1; SurfNum <= NumOfSurfs; ++SurfNum) { - if (state.dataIPShortCut->cAlphaArgs(ListSurfNum) == state.dataSurface->Surface(SurfFirst + SurfNum).Name) { - state.dataRoomAirMod->AirNode(AirNodeNum).SurfMask(SurfNum) = true; - ++SurfCount; + for (int ListSurfNum = 4; ListSurfNum <= NumAlphas; ++ListSurfNum) { + int thisSurfinZone = 0; + bool surfaceFound = false; + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { + ++thisSurfinZone; + if (state.dataIPShortCut->cAlphaArgs(ListSurfNum) == state.dataSurface->Surface(SurfNum).Name) { + ; + state.dataRoomAirMod->AirNode(AirNodeNum).SurfMask(thisSurfinZone) = true; + ++SurfCount; + surfaceFound = true; + break; + } } + if (surfaceFound) break; } } @@ -832,7 +853,7 @@ namespace RoomAirModelManager { // this zone uses a nodal air model so get number of air nodes in each zone for (AirNodeNum = 1; AirNodeNum <= state.dataRoomAirMod->TotNumOfAirNodes; ++AirNodeNum) { - if (UtilityRoutines::SameString(state.dataRoomAirMod->AirNode(AirNodeNum).ZoneName, state.dataHeatBal->Zone(ZoneNum).Name)) { + if (state.dataRoomAirMod->AirNode(AirNodeNum).ZonePtr == ZoneNum) { ++state.dataRoomAirMod->TotNumOfZoneAirNodes(ZoneNum); } } @@ -1381,10 +1402,6 @@ namespace RoomAirModelManager { bool foundList; int NumSurfsThisNode; int NumOfSurfs; - int SurfCount; - int SurfFirst; - int ListSurfNum; - int SurfNum; int gainsLoop; int TypeNum; int numEquip; @@ -1479,8 +1496,11 @@ namespace RoomAirModelManager { } else { state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).ControlAirNodeID = AirCntrlNodeNum; } - state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).totNumSurfs = - state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast - state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst + 1; + state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).totNumSurfs = 0; + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).totNumSurfs += thisSpace.HTSurfaceLast - thisSpace.HTSurfaceFirst + 1; + } } // loop thru NumOfRoomAirflowNetControl cCurrentModuleObject = "RoomAir:Node:AirflowNetwork"; @@ -1571,7 +1591,11 @@ namespace RoomAirModelManager { if (RAFNNodeNum > 0) { // found it foundList = true; NumSurfsThisNode = NumAlphas - 1; - NumOfSurfs = state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast - state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst + 1; + NumOfSurfs = 0; + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + NumOfSurfs += thisSpace.HTSurfaceLast - thisSpace.HTSurfaceFirst + 1; + } if (allocated(state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(RAFNNodeNum).SurfMask)) { // throw error found twice ShowSevereError(state, @@ -1587,16 +1611,22 @@ namespace RoomAirModelManager { state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(RAFNNodeNum).SurfMask = false; // init state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(RAFNNodeNum).HasSurfacesAssigned = true; // relate surfaces to this air node and check to see whether surface names are specified correctly or not - SurfCount = 0; - SurfFirst = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst - 1; - for (ListSurfNum = 2; ListSurfNum <= NumAlphas; ++ListSurfNum) { - for (SurfNum = 1; SurfNum <= NumOfSurfs; ++SurfNum) { - // IF( cAlphaArgs( ListSurfNum ) == Surface( SurfFirst + SurfNum ).Name ) THEN - if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(ListSurfNum), - state.dataSurface->Surface(SurfFirst + SurfNum).Name)) { - state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(RAFNNodeNum).SurfMask(SurfNum) = true; - SurfCount = SurfCount + 1; + int SurfCount = 0; + int thisSurfinZone = 0; + bool surfaceFound = false; + for (int ListSurfNum = 2; ListSurfNum <= NumAlphas; ++ListSurfNum) { + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { + ++thisSurfinZone; + if (state.dataIPShortCut->cAlphaArgs(ListSurfNum) == state.dataSurface->Surface(SurfNum).Name) { + state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(RAFNNodeNum).SurfMask(thisSurfinZone) = true; + ++SurfCount; + surfaceFound = true; + break; + } } + if (surfaceFound) break; } } if (NumSurfsThisNode != SurfCount) { @@ -1923,7 +1953,7 @@ namespace RoomAirModelManager { } } - void SharedDVCVUFDataInit(EnergyPlusData &state, int &ZoneNum) + void SharedDVCVUFDataInit(EnergyPlusData &state, int const ZoneNum) { // SUBROUTINE INFORMATION: @@ -1944,7 +1974,6 @@ namespace RoomAirModelManager { // Using/Aliasing using namespace DataEnvironment; - using namespace DataHeatBalFanSys; using namespace DataSurfaces; using Psychrometrics::PsyRhoAirFnPbTdbW; @@ -1961,8 +1990,6 @@ namespace RoomAirModelManager { // na // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int SurfNum; // DO loop counter for surfaces - int ZNum; // DO loop counter for zones bool SetZoneAux; Array1D_int AuxSurf; int MaxSurf; @@ -2026,7 +2053,7 @@ namespace RoomAirModelManager { state.dataUCSDShared->HDoor = 0.0; // Put the surface and zone information in Apos and PosZ arrays - for (ZNum = 1; ZNum <= state.dataGlobal->NumOfZones; ++ZNum) { + for (int ZNum = 1; ZNum <= state.dataGlobal->NumOfZones; ++ZNum) { // advance ONE position in the arrays PosZ because this is a new zone state.dataRoomAirModelMgr->contWallBegin = state.dataRoomAirModelMgr->contWall + 1; state.dataRoomAirModelMgr->contFloorBegin = state.dataRoomAirModelMgr->contFloor + 1; @@ -2037,54 +2064,57 @@ namespace RoomAirModelManager { SetZoneAux = true; // cycle in this zone for all the surfaces - for (SurfNum = state.dataHeatBal->Zone(ZNum).HTSurfaceFirst; SurfNum <= state.dataHeatBal->Zone(ZNum).HTSurfaceLast; ++SurfNum) { - if (state.dataSurface->Surface(SurfNum).Class != DataSurfaces::SurfaceClass::IntMass) { - // Recalculate lowest and highest height for the zone - state.dataRoomAirModelMgr->Z1ofZone = std::numeric_limits::max(); - state.dataRoomAirModelMgr->Z2ofZone = std::numeric_limits::lowest(); - for (int i = 1, u = state.dataSurface->Surface(SurfNum).Sides; i <= u; ++i) { - Real64 const z_i(state.dataSurface->Surface(SurfNum).Vertex(i).z); - state.dataRoomAirModelMgr->Z1ofZone = std::min(state.dataRoomAirModelMgr->Z1ofZone, z_i); - state.dataRoomAirModelMgr->Z2ofZone = std::max(state.dataRoomAirModelMgr->Z2ofZone, z_i); + for (int spaceNum : state.dataHeatBal->Zone(ZNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { + if (state.dataSurface->Surface(SurfNum).Class != DataSurfaces::SurfaceClass::IntMass) { + // Recalculate lowest and highest height for the zone + state.dataRoomAirModelMgr->Z1ofZone = std::numeric_limits::max(); + state.dataRoomAirModelMgr->Z2ofZone = std::numeric_limits::lowest(); + for (int i = 1, u = state.dataSurface->Surface(SurfNum).Sides; i <= u; ++i) { + Real64 const z_i(state.dataSurface->Surface(SurfNum).Vertex(i).z); + state.dataRoomAirModelMgr->Z1ofZone = std::min(state.dataRoomAirModelMgr->Z1ofZone, z_i); + state.dataRoomAirModelMgr->Z2ofZone = std::max(state.dataRoomAirModelMgr->Z2ofZone, z_i); + } } - } - if (SetZoneAux) { - // lowest height for the zone (for the first surface of the zone) - state.dataRoomAirModelMgr->Z1ofZoneAux = state.dataRoomAirModelMgr->Z1ofZone; - // highest height for the zone (for the first surface of the zone) - state.dataRoomAirModelMgr->Z2ofZoneAux = state.dataRoomAirModelMgr->Z2ofZone; - SetZoneAux = false; - } + if (SetZoneAux) { + // lowest height for the zone (for the first surface of the zone) + state.dataRoomAirModelMgr->Z1ofZoneAux = state.dataRoomAirModelMgr->Z1ofZone; + // highest height for the zone (for the first surface of the zone) + state.dataRoomAirModelMgr->Z2ofZoneAux = state.dataRoomAirModelMgr->Z2ofZone; + SetZoneAux = false; + } - if (state.dataRoomAirModelMgr->Z1ofZone < state.dataRoomAirModelMgr->Z1ofZoneAux) { - state.dataRoomAirModelMgr->Z1ofZoneAux = state.dataRoomAirModelMgr->Z1ofZone; - } - if (state.dataRoomAirModelMgr->Z2ofZone > state.dataRoomAirModelMgr->Z2ofZoneAux) { - state.dataRoomAirModelMgr->Z2ofZoneAux = state.dataRoomAirModelMgr->Z2ofZone; - } - state.dataRoomAirModelMgr->Z1ofZone = state.dataRoomAirModelMgr->Z1ofZoneAux; - state.dataRoomAirModelMgr->Z2ofZone = state.dataRoomAirModelMgr->Z2ofZoneAux; - - // Put the reference to this surface in the appropriate array - if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Floor) { - ++state.dataRoomAirModelMgr->contFloor; - state.dataUCSDShared->APos_Floor(state.dataRoomAirModelMgr->contFloor) = SurfNum; - } else if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Wall) { - ++state.dataRoomAirModelMgr->contWall; - state.dataUCSDShared->APos_Wall(state.dataRoomAirModelMgr->contWall) = SurfNum; - } else if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Window) { - ++state.dataRoomAirModelMgr->contWindow; - state.dataUCSDShared->APos_Window(state.dataRoomAirModelMgr->contWindow) = SurfNum; - } else if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::IntMass) { - ++state.dataRoomAirModelMgr->contInternal; - state.dataUCSDShared->APos_Internal(state.dataRoomAirModelMgr->contInternal) = SurfNum; - } else if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Door) { - ++state.dataRoomAirModelMgr->contDoor; - state.dataUCSDShared->APos_Door(state.dataRoomAirModelMgr->contDoor) = SurfNum; - } else { - ++state.dataRoomAirModelMgr->contCeiling; - state.dataUCSDShared->APos_Ceiling(state.dataRoomAirModelMgr->contCeiling) = SurfNum; + if (state.dataRoomAirModelMgr->Z1ofZone < state.dataRoomAirModelMgr->Z1ofZoneAux) { + state.dataRoomAirModelMgr->Z1ofZoneAux = state.dataRoomAirModelMgr->Z1ofZone; + } + if (state.dataRoomAirModelMgr->Z2ofZone > state.dataRoomAirModelMgr->Z2ofZoneAux) { + state.dataRoomAirModelMgr->Z2ofZoneAux = state.dataRoomAirModelMgr->Z2ofZone; + } + state.dataRoomAirModelMgr->Z1ofZone = state.dataRoomAirModelMgr->Z1ofZoneAux; + state.dataRoomAirModelMgr->Z2ofZone = state.dataRoomAirModelMgr->Z2ofZoneAux; + + // Put the reference to this surface in the appropriate array + if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Floor) { + ++state.dataRoomAirModelMgr->contFloor; + state.dataUCSDShared->APos_Floor(state.dataRoomAirModelMgr->contFloor) = SurfNum; + } else if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Wall) { + ++state.dataRoomAirModelMgr->contWall; + state.dataUCSDShared->APos_Wall(state.dataRoomAirModelMgr->contWall) = SurfNum; + } else if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Window) { + ++state.dataRoomAirModelMgr->contWindow; + state.dataUCSDShared->APos_Window(state.dataRoomAirModelMgr->contWindow) = SurfNum; + } else if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::IntMass) { + ++state.dataRoomAirModelMgr->contInternal; + state.dataUCSDShared->APos_Internal(state.dataRoomAirModelMgr->contInternal) = SurfNum; + } else if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Door) { + ++state.dataRoomAirModelMgr->contDoor; + state.dataUCSDShared->APos_Door(state.dataRoomAirModelMgr->contDoor) = SurfNum; + } else { + ++state.dataRoomAirModelMgr->contCeiling; + state.dataUCSDShared->APos_Ceiling(state.dataRoomAirModelMgr->contCeiling) = SurfNum; + } } } // Surfaces @@ -2168,7 +2198,7 @@ namespace RoomAirModelManager { state.dataRoomAirMod->AirflowNetworkSurfaceUCSDCV(0, state.dataRoomAirModelMgr->Loop) = AuxSurf(state.dataRoomAirModelMgr->Loop); if (AuxSurf(state.dataRoomAirModelMgr->Loop) != 0) { Real64 const ceilingHeight(state.dataRoomAirMod->ZoneCeilingHeight((state.dataRoomAirModelMgr->Loop - 1) * 2 + 1)); - SurfNum = 1; + int SurfNum = 1; for (state.dataRoomAirModelMgr->Loop2 = 1; state.dataRoomAirModelMgr->Loop2 <= state.afn->NumOfLinksMultiZone; ++state.dataRoomAirModelMgr->Loop2) { if (state.dataSurface->Surface(state.afn->MultizoneSurfaceData(state.dataRoomAirModelMgr->Loop2).SurfNum).Zone == @@ -2220,12 +2250,16 @@ namespace RoomAirModelManager { AirflowNetwork::iComponentTypeNum::SCR) { // surface type = CRACK state.dataRoomAirMod->SurfParametersCVDV(state.dataRoomAirModelMgr->Loop2).Width = state.dataSurface->Surface(state.afn->MultizoneSurfaceData(state.dataRoomAirModelMgr->Loop2).SurfNum).Width / 2; - AinCV = state.afn->MultizoneSurfaceCrackData(state.dataRoomAirModelMgr->TypeNumber).coefficient / - (BaseDischargeCoef * - std::sqrt(2.0 / PsyRhoAirFnPbTdbW(state, - state.dataEnvrn->OutBaroPress, - state.dataHeatBalFanSys->MAT(state.dataRoomAirModelMgr->Loop), - state.dataHeatBalFanSys->ZoneAirHumRat(state.dataRoomAirModelMgr->Loop)))); + AinCV = + state.afn->MultizoneSurfaceCrackData(state.dataRoomAirModelMgr->TypeNumber).coefficient / + (BaseDischargeCoef * + std::sqrt( + 2.0 / + PsyRhoAirFnPbTdbW( + state, + state.dataEnvrn->OutBaroPress, + state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataRoomAirModelMgr->Loop).MAT, + state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataRoomAirModelMgr->Loop).ZoneAirHumRat))); state.dataRoomAirMod->SurfParametersCVDV(state.dataRoomAirModelMgr->Loop2).Height = AinCV / state.dataRoomAirMod->SurfParametersCVDV(state.dataRoomAirModelMgr->Loop2).Width; } @@ -2806,7 +2840,6 @@ namespace RoomAirModelManager { ++state.dataRoomAirModelMgr->i) { state.dataRoomAirModelMgr->N = state.afn->AirflowNetworkLinkageData(state.dataRoomAirModelMgr->i).CompNum; if (state.afn->AirflowNetworkCompData(state.dataRoomAirModelMgr->N).CompTypeNum == AirflowNetwork::iComponentTypeNum::DOP) { - SurfNum = state.afn->MultizoneSurfaceData(state.dataRoomAirModelMgr->i).SurfNum; SetupOutputVariable( state, "Room Air Window Jet Region Average Air Velocity", diff --git a/src/EnergyPlus/RoomAirModelManager.hh b/src/EnergyPlus/RoomAirModelManager.hh index 127deb23178..244995e2318 100644 --- a/src/EnergyPlus/RoomAirModelManager.hh +++ b/src/EnergyPlus/RoomAirModelManager.hh @@ -59,7 +59,7 @@ struct EnergyPlusData; namespace RoomAirModelManager { - void ManageAirModel(EnergyPlusData &state, int &ZoneNum); + void ManageAirModel(EnergyPlusData &state, int const ZoneNum); void GetAirModelDatas(EnergyPlusData &state); @@ -75,7 +75,7 @@ namespace RoomAirModelManager { void GetUFADZoneData(EnergyPlusData &state, bool &ErrorsFound); // True if errors found during this get input routine - void SharedDVCVUFDataInit(EnergyPlusData &state, int &ZoneNum); + void SharedDVCVUFDataInit(EnergyPlusData &state, int const ZoneNum); void GetRoomAirflowNetworkData(EnergyPlusData &state, bool &ErrorsFound); // True if errors found during this get input routine diff --git a/src/EnergyPlus/RoomAirModelUserTempPattern.cc b/src/EnergyPlus/RoomAirModelUserTempPattern.cc index 55b47830f4f..29834a06860 100644 --- a/src/EnergyPlus/RoomAirModelUserTempPattern.cc +++ b/src/EnergyPlus/RoomAirModelUserTempPattern.cc @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -71,6 +72,7 @@ #include #include #include +#include namespace EnergyPlus::RoomAirModelUserTempPattern { @@ -180,15 +182,15 @@ void GetSurfHBDataForTempDistModel(EnergyPlusData &state, int const ZoneNum) // // Using/Aliasing // intialize in preperation for calculations - state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).Tstat = state.dataHeatBalFanSys->MAT(ZoneNum); - state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).Tleaving = state.dataHeatBalFanSys->MAT(ZoneNum); - state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).Texhaust = state.dataHeatBalFanSys->MAT(ZoneNum); + state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).Tstat = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; + state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).Tleaving = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; + state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).Texhaust = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; for (auto &e : state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).Surf) - e.TadjacentAir = state.dataHeatBalFanSys->MAT(ZoneNum); + e.TadjacentAir = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; // the only input this method needs is the zone MAT or ZT or ZTAV ? (original was ZT) state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).TairMean = - state.dataHeatBalFanSys->MAT(ZoneNum); // this is lagged from previous corrector result + state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; // this is lagged from previous corrector result } //***************************************************************************************** @@ -480,7 +482,7 @@ void FigureTwoGradInterpPattern(EnergyPlusData &state, int const PattrnID, int c } } break; case DataRoomAirModel::UserDefinedPatternMode::SensibleCooling: { - CoolLoad = state.dataHeatBal->ZoneSNLoadCoolRate(ZoneNum); + CoolLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).ZoneSNLoadCoolRate; if (CoolLoad >= state.dataRoomAirMod->RoomAirPattern(PattrnID).TwoGradPatrn.UpperBoundHeatRateScale) { Grad = state.dataRoomAirMod->RoomAirPattern(PattrnID).TwoGradPatrn.HiGradient; @@ -503,7 +505,7 @@ void FigureTwoGradInterpPattern(EnergyPlusData &state, int const PattrnID, int c } } break; case DataRoomAirModel::UserDefinedPatternMode::SensibleHeating: { - HeatLoad = state.dataHeatBal->ZoneSNLoadHeatRate(ZoneNum); + HeatLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).ZoneSNLoadHeatRate; if (HeatLoad >= state.dataRoomAirMod->RoomAirPattern(PattrnID).TwoGradPatrn.UpperBoundHeatRateScale) { Grad = state.dataRoomAirMod->RoomAirPattern(PattrnID).TwoGradPatrn.HiGradient; @@ -660,7 +662,6 @@ Real64 FigureNDheightInZone(EnergyPlusData &state, int const thisHBsurf) // inde Real64 ZMax; Real64 ZMin; int Count; - int SurfNum; Real64 Z1; Real64 Z2; @@ -675,23 +676,26 @@ Real64 FigureNDheightInZone(EnergyPlusData &state, int const thisHBsurf) // inde ZMax = 0.0; ZMin = 0.0; Count = 0; - for (SurfNum = state.dataHeatBal->Zone(thisZone).HTSurfaceFirst; SurfNum <= state.dataHeatBal->Zone(thisZone).HTSurfaceLast; ++SurfNum) { - if (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Floor) { - // Use Average Z for surface, more important for roofs than floors... - ++FloorCount; - Z1 = minval(state.dataSurface->Surface(SurfNum).Vertex({1, state.dataSurface->Surface(SurfNum).Sides}), &Vector::z); - Z2 = maxval(state.dataSurface->Surface(SurfNum).Vertex({1, state.dataSurface->Surface(SurfNum).Sides}), &Vector::z); - ZFlrAvg += (Z1 + Z2) / 2.0; - } - if (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Wall) { - // Use Wall calculation in case no floor in zone - ++Count; - if (Count == 1) { - ZMax = state.dataSurface->Surface(SurfNum).Vertex(1).z; - ZMin = ZMax; + for (int spaceNum : state.dataHeatBal->Zone(thisZone).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { + if (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Floor) { + // Use Average Z for surface, more important for roofs than floors... + ++FloorCount; + Z1 = minval(state.dataSurface->Surface(SurfNum).Vertex({1, state.dataSurface->Surface(SurfNum).Sides}), &Vector::z); + Z2 = maxval(state.dataSurface->Surface(SurfNum).Vertex({1, state.dataSurface->Surface(SurfNum).Sides}), &Vector::z); + ZFlrAvg += (Z1 + Z2) / 2.0; + } + if (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Wall) { + // Use Wall calculation in case no floor in zone + ++Count; + if (Count == 1) { + ZMax = state.dataSurface->Surface(SurfNum).Vertex(1).z; + ZMin = ZMax; + } + ZMax = max(ZMax, maxval(state.dataSurface->Surface(SurfNum).Vertex({1, state.dataSurface->Surface(SurfNum).Sides}), &Vector::z)); + ZMin = min(ZMin, minval(state.dataSurface->Surface(SurfNum).Vertex({1, state.dataSurface->Surface(SurfNum).Sides}), &Vector::z)); } - ZMax = max(ZMax, maxval(state.dataSurface->Surface(SurfNum).Vertex({1, state.dataSurface->Surface(SurfNum).Sides}), &Vector::z)); - ZMin = min(ZMin, minval(state.dataSurface->Surface(SurfNum).Vertex({1, state.dataSurface->Surface(SurfNum).Sides}), &Vector::z)); } } if (FloorCount > 0.0) { @@ -765,7 +769,6 @@ void SetSurfHBDataForTempDistModel(EnergyPlusData &state, int const ZoneNum) // // Using/Aliasing using DataHVACGlobals::RetTempMax; using DataHVACGlobals::RetTempMin; - using InternalHeatGains::SumAllReturnAirConvectionGains; using InternalHeatGains::SumAllReturnAirLatentGains; using Psychrometrics::PsyCpAirFnW; using Psychrometrics::PsyHFnTdbW; @@ -773,14 +776,11 @@ void SetSurfHBDataForTempDistModel(EnergyPlusData &state, int const ZoneNum) // using Psychrometrics::PsyRhoAirFnPbTdbW; // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int SurfFirst; // index number of the first surface in the zone - int SurfLast; Real64 QRetAir; // Heat to return air from lights Real64 CpAir; // Air heat capacity [J/kg-K] Real64 TempRetAir; // Return air temperature [C] Real64 TempZoneAir; // Zone air temperature [C] int ZoneNode; // Node number of controlled zone - int SurfNum; // Surface number Real64 MassFlowRA; // Return air mass flow [kg/s] Real64 FlowThisTS; // Window gap air mass flow [kg/s] Real64 WinGapFlowToRA; // Mass flow to return air from all airflow windows in zone [kg/s] @@ -791,9 +791,6 @@ void SetSurfHBDataForTempDistModel(EnergyPlusData &state, int const ZoneNum) // Real64 ZoneMult; Real64 SumRetAirLatentGainRate; - SurfFirst = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst; - SurfLast = state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast; - // set air system leaving node conditions // this is not so easy. THis task is normally done in CalcZoneLeavingConditions // but efforts to do this update there were not successful. @@ -806,6 +803,7 @@ void SetSurfHBDataForTempDistModel(EnergyPlusData &state, int const ZoneNum) // state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).Tleaving; } + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); for (int nodeCount = 1; nodeCount <= state.dataZoneEquip->ZoneEquipConfig(ZoneNum).NumReturnNodes; ++nodeCount) { // BEGIN BLOCK of code from CalcZoneLeavingConditions********************************* int ReturnNode = state.dataZoneEquip->ZoneEquipConfig(ZoneNum).ReturnNode(nodeCount); @@ -813,7 +811,7 @@ void SetSurfHBDataForTempDistModel(EnergyPlusData &state, int const ZoneNum) // ZoneMult = state.dataHeatBal->Zone(ZoneNum).Multiplier * state.dataHeatBal->Zone(ZoneNum).ListMultiplier; // RETURN AIR HEAT GAIN from the Lights statement; this heat gain is stored in // Add sensible heat gain from refrigerated cases with under case returns - QRetAir = SumAllReturnAirConvectionGains(state, ZoneNum, ReturnNode); + QRetAir = InternalHeatGains::zoneSumAllReturnAirConvectionGains(state, ZoneNum, ReturnNode); CpAir = PsyCpAirFnW(state.dataLoopNodes->Node(ZoneNode).HumRat); @@ -830,16 +828,19 @@ void SetSurfHBDataForTempDistModel(EnergyPlusData &state, int const ZoneNum) // WinGapFlowTtoRA = 0.0; if (state.dataHeatBal->Zone(ZoneNum).HasAirFlowWindowReturn) { - for (SurfNum = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst; SurfNum <= state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast; ++SurfNum) { - if (state.dataSurface->SurfWinAirflowThisTS(SurfNum) > 0.0 && - state.dataSurface->SurfWinAirflowDestination(SurfNum) == DataSurfaces::WindowAirFlowDestination::Return) { - FlowThisTS = PsyRhoAirFnPbTdbW(state, - state.dataEnvrn->OutBaroPress, - state.dataSurface->SurfWinTAirflowGapOutlet(SurfNum), - state.dataLoopNodes->Node(ZoneNode).HumRat) * - state.dataSurface->SurfWinAirflowThisTS(SurfNum) * state.dataSurface->Surface(SurfNum).Width; - WinGapFlowToRA += FlowThisTS; - WinGapFlowTtoRA += FlowThisTS * state.dataSurface->SurfWinTAirflowGapOutlet(SurfNum); + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &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) { + FlowThisTS = PsyRhoAirFnPbTdbW(state, + state.dataEnvrn->OutBaroPress, + state.dataSurface->SurfWinTAirflowGapOutlet(SurfNum), + state.dataLoopNodes->Node(ZoneNode).HumRat) * + state.dataSurface->SurfWinAirflowThisTS(SurfNum) * state.dataSurface->Surface(SurfNum).Width; + WinGapFlowToRA += FlowThisTS; + WinGapFlowTtoRA += FlowThisTS * state.dataSurface->SurfWinTAirflowGapOutlet(SurfNum); + } } } } @@ -855,7 +856,7 @@ void SetSurfHBDataForTempDistModel(EnergyPlusData &state, int const ZoneNum) // // All of return air comes from flow through airflow windows TempRetAir = WinGapTtoRA; // Put heat from window airflow that exceeds return air flow into zone air - state.dataHeatBalFanSys->SysDepZoneLoads(ZoneNum) += (WinGapFlowToRA - MassFlowRA) * CpAir * (WinGapTtoRA - TempZoneAir); + thisZoneHB.SysDepZoneLoads += (WinGapFlowToRA - MassFlowRA) * CpAir * (WinGapTtoRA - TempZoneAir); } } // Add heat-to-return from lights @@ -863,21 +864,21 @@ void SetSurfHBDataForTempDistModel(EnergyPlusData &state, int const ZoneNum) // if (TempRetAir > RetTempMax) { state.dataLoopNodes->Node(ReturnNode).Temp = RetTempMax; if (!state.dataGlobal->ZoneSizingCalc) { - state.dataHeatBalFanSys->SysDepZoneLoads(ZoneNum) += CpAir * MassFlowRA * (TempRetAir - RetTempMax); + thisZoneHB.SysDepZoneLoads += CpAir * MassFlowRA * (TempRetAir - RetTempMax); } } else if (TempRetAir < RetTempMin) { state.dataLoopNodes->Node(ReturnNode).Temp = RetTempMin; if (!state.dataGlobal->ZoneSizingCalc) { - state.dataHeatBalFanSys->SysDepZoneLoads(ZoneNum) += CpAir * MassFlowRA * (TempRetAir - RetTempMin); + thisZoneHB.SysDepZoneLoads += CpAir * MassFlowRA * (TempRetAir - RetTempMin); } } else { state.dataLoopNodes->Node(ReturnNode).Temp = TempRetAir; } } else { // No return air flow // Assign all heat-to-return from window gap airflow to zone air - if (WinGapFlowToRA > 0.0) state.dataHeatBalFanSys->SysDepZoneLoads(ZoneNum) += WinGapFlowToRA * CpAir * (WinGapTtoRA - TempZoneAir); + if (WinGapFlowToRA > 0.0) thisZoneHB.SysDepZoneLoads += WinGapFlowToRA * CpAir * (WinGapTtoRA - TempZoneAir); // Assign all heat-to-return from lights to zone air - if (QRetAir > 0.0) state.dataHeatBalFanSys->SysDepZoneLoads(ZoneNum) += QRetAir; + if (QRetAir > 0.0) thisZoneHB.SysDepZoneLoads += QRetAir; state.dataLoopNodes->Node(ReturnNode).Temp = state.dataLoopNodes->Node(ZoneNode).Temp; } } else { @@ -904,14 +905,14 @@ void SetSurfHBDataForTempDistModel(EnergyPlusData &state, int const ZoneNum) // state.dataHeatBal->RefrigCaseCredit(ZoneNum).LatCaseCreditToZone += state.dataHeatBal->RefrigCaseCredit(ZoneNum).LatCaseCreditToHVAC; // shouldn't the HVAC term be zeroed out then? SumRetAirLatentGainRate = SumAllReturnAirLatentGains(state, ZoneNum, 0); - state.dataHeatBalFanSys->ZoneLatentGain(ZoneNum) += SumRetAirLatentGainRate; + thisZoneHB.ZoneLatentGain += SumRetAirLatentGainRate; } } else { state.dataLoopNodes->Node(ReturnNode).HumRat = state.dataLoopNodes->Node(ZoneNode).HumRat; state.dataHeatBal->RefrigCaseCredit(ZoneNum).LatCaseCreditToZone += state.dataHeatBal->RefrigCaseCredit(ZoneNum).LatCaseCreditToHVAC; // shouldn't the HVAC term be zeroed out then? SumRetAirLatentGainRate = SumAllReturnAirLatentGains(state, ZoneNum, ReturnNode); - state.dataHeatBalFanSys->ZoneLatentGain(ZoneNum) += SumRetAirLatentGainRate; + thisZoneHB.ZoneLatentGain += SumRetAirLatentGainRate; } state.dataLoopNodes->Node(ReturnNode).Enthalpy = @@ -934,14 +935,22 @@ void SetSurfHBDataForTempDistModel(EnergyPlusData &state, int const ZoneNum) // state.dataHeatBalFanSys->TempTstatAir(ZoneNum) = state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).Tstat; // set results for all surface - for (int i = SurfFirst, j = 1; i <= SurfLast; ++i, ++j) { - state.dataHeatBal->SurfTempEffBulkAir(i) = state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).Surf(j).TadjacentAir; + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int j = 0; + for (int i = thisSpace.HTSurfaceFirst; i <= thisSpace.HTSurfaceLast; ++i) { + ++j; + state.dataHeatBal->SurfTempEffBulkAir(i) = state.dataRoomAirMod->AirPatternZoneInfo(ZoneNum).Surf(j).TadjacentAir; + } } // set flag for reference air temperature mode - for (int i = SurfFirst; i <= SurfLast; ++i) { - state.dataSurface->SurfTAirRef(i) = DataSurfaces::RefAirTemp::AdjacentAirTemp; - state.dataSurface->SurfTAirRefRpt(i) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(i)]; + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int i = thisSpace.HTSurfaceFirst; i <= thisSpace.HTSurfaceLast; ++i) { + state.dataSurface->SurfTAirRef(i) = DataSurfaces::RefAirTemp::AdjacentAirTemp; + state.dataSurface->SurfTAirRefRpt(i) = DataSurfaces::SurfTAirRefReportVals[state.dataSurface->SurfTAirRef(i)]; + } } } diff --git a/src/EnergyPlus/SimulationManager.cc b/src/EnergyPlus/SimulationManager.cc index 99ab00949b1..41b6908837a 100644 --- a/src/EnergyPlus/SimulationManager.cc +++ b/src/EnergyPlus/SimulationManager.cc @@ -239,6 +239,7 @@ namespace SimulationManager { state.dataGlobal->DoOutputReporting = true; } state.dataGlobal->DoingSizing = false; + state.dataHeatBal->doSpaceHeatBalance = state.dataHeatBal->doSpaceHeatBalanceSimulation; if ((state.dataGlobal->DoZoneSizing || state.dataGlobal->DoSystemSizing || state.dataGlobal->DoPlantSizing) && !(state.dataGlobal->DoDesDaySim || (state.dataGlobal->DoWeathSim && state.dataSimulationManager->RunPeriodsInInput))) { diff --git a/src/EnergyPlus/SolarShading.cc b/src/EnergyPlus/SolarShading.cc index f8523c719b1..b7476b84382 100644 --- a/src/EnergyPlus/SolarShading.cc +++ b/src/EnergyPlus/SolarShading.cc @@ -63,7 +63,6 @@ #include #include #include -#include #include #include #include @@ -74,6 +73,7 @@ #include #include #include +#include #include #include #include @@ -92,6 +92,7 @@ #include #include #include +#include #include namespace EnergyPlus::SolarShading { @@ -291,54 +292,57 @@ void InitSolarCalculations(EnergyPlusData &state) state.dataHeatBal->SurfInitialDifSolInAbsReport(SurfNum) = 0.0; } for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceFirst; - int const lastSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceLast; - for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurfWin = thisSpace.WindowSurfaceFirst; + int const lastSurfWin = thisSpace.WindowSurfaceLast; + for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { - state.dataSurface->SurfWinTransSolar(SurfNum) = 0.0; - state.dataSurface->SurfWinBmSolar(SurfNum) = 0.0; - state.dataSurface->SurfWinBmBmSolar(SurfNum) = 0.0; - state.dataSurface->SurfWinBmDifSolar(SurfNum) = 0.0; - state.dataSurface->SurfWinDifSolar(SurfNum) = 0.0; + state.dataSurface->SurfWinTransSolar(SurfNum) = 0.0; + state.dataSurface->SurfWinBmSolar(SurfNum) = 0.0; + state.dataSurface->SurfWinBmBmSolar(SurfNum) = 0.0; + state.dataSurface->SurfWinBmDifSolar(SurfNum) = 0.0; + state.dataSurface->SurfWinDifSolar(SurfNum) = 0.0; - state.dataSurface->SurfWinTransSolarEnergy(SurfNum) = 0.0; - state.dataSurface->SurfWinBmSolarEnergy(SurfNum) = 0.0; - state.dataSurface->SurfWinBmBmSolarEnergy(SurfNum) = 0.0; - state.dataSurface->SurfWinBmDifSolarEnergy(SurfNum) = 0.0; + state.dataSurface->SurfWinTransSolarEnergy(SurfNum) = 0.0; + state.dataSurface->SurfWinBmSolarEnergy(SurfNum) = 0.0; + state.dataSurface->SurfWinBmBmSolarEnergy(SurfNum) = 0.0; + state.dataSurface->SurfWinBmDifSolarEnergy(SurfNum) = 0.0; - state.dataSurface->SurfWinHeatGain(SurfNum) = 0.0; - state.dataSurface->SurfWinHeatGainRep(SurfNum) = 0.0; - state.dataSurface->SurfWinHeatLossRep(SurfNum) = 0.0; - } - for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { - state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) = 0.0; - state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) = 0.0; - state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) = 0.0; - state.dataSurface->SurfWinGainFrameDividerToZoneRep(SurfNum) = 0.0; - state.dataSurface->SurfWinGainConvShadeToZoneRep(SurfNum) = 0.0; - state.dataSurface->SurfWinGainIRShadeToZoneRep(SurfNum) = 0.0; - state.dataSurface->SurfWinGapConvHtFlowRep(SurfNum) = 0.0; - state.dataSurface->SurfWinShadingAbsorbedSolar(SurfNum) = 0.0; - - state.dataSurface->SurfWinSysSolTransmittance(SurfNum) = 0.0; - state.dataSurface->SurfWinSysSolReflectance(SurfNum) = 0.0; - state.dataSurface->SurfWinSysSolAbsorptance(SurfNum) = 0.0; - } - for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { - state.dataSurface->SurfWinDifSolarEnergy(SurfNum) = 0.0; - state.dataSurface->SurfWinHeatGainRepEnergy(SurfNum) = 0.0; - state.dataSurface->SurfWinHeatLossRepEnergy(SurfNum) = 0.0; - state.dataSurface->SurfWinGapConvHtFlowRepEnergy(SurfNum) = 0.0; - state.dataSurface->SurfWinShadingAbsorbedSolarEnergy(SurfNum) = 0.0; + state.dataSurface->SurfWinHeatGain(SurfNum) = 0.0; + state.dataSurface->SurfWinHeatGainRep(SurfNum) = 0.0; + state.dataSurface->SurfWinHeatLossRep(SurfNum) = 0.0; + } + for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { + state.dataSurface->SurfWinGainConvGlazToZoneRep(SurfNum) = 0.0; + state.dataSurface->SurfWinGainIRGlazToZoneRep(SurfNum) = 0.0; + state.dataSurface->SurfWinLossSWZoneToOutWinRep(SurfNum) = 0.0; + state.dataSurface->SurfWinGainFrameDividerToZoneRep(SurfNum) = 0.0; + state.dataSurface->SurfWinGainConvShadeToZoneRep(SurfNum) = 0.0; + state.dataSurface->SurfWinGainIRShadeToZoneRep(SurfNum) = 0.0; + state.dataSurface->SurfWinGapConvHtFlowRep(SurfNum) = 0.0; + state.dataSurface->SurfWinShadingAbsorbedSolar(SurfNum) = 0.0; - state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0; - state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) = 0.0; - state.dataHeatBal->SurfWinSWwinAbsTotalReport(SurfNum) = 0.0; - state.dataHeatBal->SurfWinInitialDifSolInTransReport(SurfNum) = 0.0; + state.dataSurface->SurfWinSysSolTransmittance(SurfNum) = 0.0; + state.dataSurface->SurfWinSysSolReflectance(SurfNum) = 0.0; + state.dataSurface->SurfWinSysSolAbsorptance(SurfNum) = 0.0; + } + for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { + state.dataSurface->SurfWinDifSolarEnergy(SurfNum) = 0.0; + state.dataSurface->SurfWinHeatGainRepEnergy(SurfNum) = 0.0; + state.dataSurface->SurfWinHeatLossRepEnergy(SurfNum) = 0.0; + state.dataSurface->SurfWinGapConvHtFlowRepEnergy(SurfNum) = 0.0; + state.dataSurface->SurfWinShadingAbsorbedSolarEnergy(SurfNum) = 0.0; - state.dataSurface->SurfWinInsideGlassCondensationFlag(SurfNum) = 0; - state.dataSurface->SurfWinInsideFrameCondensationFlag(SurfNum) = 0; - state.dataSurface->SurfWinInsideDividerCondensationFlag(SurfNum) = 0; + state.dataHeatBal->SurfWinQRadSWwinAbsTot(SurfNum) = 0.0; + state.dataHeatBal->SurfWinQRadSWwinAbsTotEnergy(SurfNum) = 0.0; + state.dataHeatBal->SurfWinSWwinAbsTotalReport(SurfNum) = 0.0; + state.dataHeatBal->SurfWinInitialDifSolInTransReport(SurfNum) = 0.0; + + state.dataSurface->SurfWinInsideGlassCondensationFlag(SurfNum) = 0; + state.dataSurface->SurfWinInsideFrameCondensationFlag(SurfNum) = 0; + state.dataSurface->SurfWinInsideDividerCondensationFlag(SurfNum) = 0; + } } } } @@ -4806,37 +4810,40 @@ void CalcPerSolarBeam(EnergyPlusData &state, // Initialize some values for the appropriate period if (!state.dataSysVars->DetailedSolarTimestepIntegration) { for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int firstSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceFirst; - int lastSurf = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceLast; - for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - state.dataSurface->SurfOpaqAO(surfNum) = 0.0; - } - firstSurf = state.dataHeatBal->Zone(zoneNum).HTSurfaceFirst; - lastSurf = state.dataHeatBal->Zone(zoneNum).HTSurfaceLast; - for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - state.dataSolarShading->SurfSunCosTheta(surfNum) = 0.0; - } - for (int hour = 1; hour <= 24; ++hour) { + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int firstSurf = thisSpace.OpaqOrIntMassSurfaceFirst; + int lastSurf = thisSpace.OpaqOrIntMassSurfaceLast; for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - state.dataHeatBal->SurfSunlitFracHR(hour, surfNum) = 0.0; - state.dataHeatBal->SurfCosIncAngHR(hour, surfNum) = 0.0; + state.dataSurface->SurfOpaqAO(surfNum) = 0.0; } - } - for (int hour = 1; hour <= 24; ++hour) { - for (int timestep = 1; timestep <= state.dataGlobal->NumOfTimeStepInHour; ++timestep) { + firstSurf = thisSpace.HTSurfaceFirst; + lastSurf = thisSpace.HTSurfaceLast; + for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { + state.dataSolarShading->SurfSunCosTheta(surfNum) = 0.0; + } + for (int hour = 1; hour <= 24; ++hour) { for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - state.dataHeatBal->SurfSunlitFrac(hour, timestep, surfNum) = 0.0; - state.dataHeatBal->SurfCosIncAng(hour, timestep, surfNum) = 0.0; - state.dataHeatBal->SurfSunlitFracWithoutReveal(hour, timestep, surfNum) = 0.0; + state.dataHeatBal->SurfSunlitFracHR(hour, surfNum) = 0.0; + state.dataHeatBal->SurfCosIncAngHR(hour, surfNum) = 0.0; } } - } - for (int hour = 1; hour <= 24; ++hour) { - for (int timestep = 1; timestep <= state.dataGlobal->NumOfTimeStepInHour; ++timestep) { - for (int backSurfNum = 1; backSurfNum <= state.dataBSDFWindow->MaxBkSurf; ++backSurfNum) { + for (int hour = 1; hour <= 24; ++hour) { + for (int timestep = 1; timestep <= state.dataGlobal->NumOfTimeStepInHour; ++timestep) { for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - state.dataHeatBal->SurfWinBackSurfaces(hour, timestep, backSurfNum, surfNum) = 0.0; - state.dataHeatBal->SurfWinOverlapAreas(hour, timestep, backSurfNum, surfNum) = 0.0; + state.dataHeatBal->SurfSunlitFrac(hour, timestep, surfNum) = 0.0; + state.dataHeatBal->SurfCosIncAng(hour, timestep, surfNum) = 0.0; + state.dataHeatBal->SurfSunlitFracWithoutReveal(hour, timestep, surfNum) = 0.0; + } + } + } + for (int hour = 1; hour <= 24; ++hour) { + for (int timestep = 1; timestep <= state.dataGlobal->NumOfTimeStepInHour; ++timestep) { + for (int backSurfNum = 1; backSurfNum <= state.dataBSDFWindow->MaxBkSurf; ++backSurfNum) { + for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { + state.dataHeatBal->SurfWinBackSurfaces(hour, timestep, backSurfNum, surfNum) = 0.0; + state.dataHeatBal->SurfWinOverlapAreas(hour, timestep, backSurfNum, surfNum) = 0.0; + } } } } @@ -4849,21 +4856,24 @@ void CalcPerSolarBeam(EnergyPlusData &state, } } else { for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurf = state.dataHeatBal->Zone(zoneNum).HTSurfaceFirst; - int const lastSurf = state.dataHeatBal->Zone(zoneNum).HTSurfaceLast; - for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - state.dataSolarShading->SurfSunCosTheta(surfNum) = 0.0; - state.dataSurface->SurfOpaqAO(surfNum) = 0.0; - state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, surfNum) = 0.0; - state.dataHeatBal->SurfSunlitFracWithoutReveal(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, surfNum) = 0.0; - state.dataHeatBal->SurfSunlitFracHR(state.dataGlobal->HourOfDay, surfNum) = 0.0; - state.dataHeatBal->SurfCosIncAngHR(state.dataGlobal->HourOfDay, surfNum) = 0.0; - state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, surfNum) = 0.0; - } - for (int backSurfNum = 1; backSurfNum <= state.dataBSDFWindow->MaxBkSurf; ++backSurfNum) { + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurf = thisSpace.HTSurfaceFirst; + int const lastSurf = thisSpace.HTSurfaceLast; for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - state.dataHeatBal->SurfWinBackSurfaces(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, backSurfNum, surfNum) = 0; - state.dataHeatBal->SurfWinOverlapAreas(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, backSurfNum, surfNum) = 0.0; + state.dataSolarShading->SurfSunCosTheta(surfNum) = 0.0; + state.dataSurface->SurfOpaqAO(surfNum) = 0.0; + state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, surfNum) = 0.0; + state.dataHeatBal->SurfSunlitFracWithoutReveal(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, surfNum) = 0.0; + state.dataHeatBal->SurfSunlitFracHR(state.dataGlobal->HourOfDay, surfNum) = 0.0; + state.dataHeatBal->SurfCosIncAngHR(state.dataGlobal->HourOfDay, surfNum) = 0.0; + state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, surfNum) = 0.0; + } + for (int backSurfNum = 1; backSurfNum <= state.dataBSDFWindow->MaxBkSurf; ++backSurfNum) { + for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { + state.dataHeatBal->SurfWinBackSurfaces(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, backSurfNum, surfNum) = 0; + state.dataHeatBal->SurfWinOverlapAreas(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, backSurfNum, surfNum) = 0.0; + } } } } @@ -6334,20 +6344,23 @@ void CalcInteriorSolarDistribution(EnergyPlusData &state) ++state.dataTimingsData->NumIntSolarDist_Calls; #endif for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceFirst; - int const lastSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceLast; - for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { - for (int lay = 1; lay <= CFSMAXNL + 1; ++lay) { - state.dataSurface->SurfWinA(SurfNum, lay) = 0.0; + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurfWin = thisSpace.WindowSurfaceFirst; + int const lastSurfWin = thisSpace.WindowSurfaceLast; + for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { + for (int lay = 1; lay <= CFSMAXNL + 1; ++lay) { + state.dataSurface->SurfWinA(SurfNum, lay) = 0.0; + } + state.dataSolarShading->SurfWinIntBeamAbsByShadFac(SurfNum) = 0.0; + state.dataSolarShading->SurfWinExtBeamAbsByShadFac(SurfNum) = 0.0; + } + int const firstSurfOpaque = thisSpace.OpaqOrIntMassSurfaceFirst; + int const lastSurfOpaque = thisSpace.OpaqOrIntMassSurfaceLast; + for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) { + state.dataSurface->SurfOpaqAI(SurfNum) = 0.0; + state.dataSurface->SurfOpaqAO(SurfNum) = 0.0; } - state.dataSolarShading->SurfWinIntBeamAbsByShadFac(SurfNum) = 0.0; - state.dataSolarShading->SurfWinExtBeamAbsByShadFac(SurfNum) = 0.0; - } - int const firstSurfOpaque = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceFirst; - int const lastSurfOpaque = state.dataHeatBal->Zone(zoneNum).OpaqOrIntMassSurfaceLast; - for (int SurfNum = firstSurfOpaque; SurfNum <= lastSurfOpaque; ++SurfNum) { - state.dataSurface->SurfOpaqAI(SurfNum) = 0.0; - state.dataSurface->SurfOpaqAO(SurfNum) = 0.0; } } if ((int)state.dataDaylightingDevicesData->TDDPipe.size() > 0) { @@ -8546,28 +8559,31 @@ void CalcAbsorbedOnExteriorOpaqueSurfaces(EnergyPlusData &state) // Calculates solar energy absorbed on exterior opaque surfaces for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { - for (int SurfNum = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst; SurfNum <= state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast; ++SurfNum) { - // TH added 3/24/2010 while debugging CR 7872 - if (!state.dataSurface->Surface(SurfNum).ExtSolar && state.dataSurface->SurfWinOriginalClass(SurfNum) != SurfaceClass::TDD_Diffuser) - continue; - int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); - int SurfNum2 = SurfNum; - if (state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::TDD_Diffuser) { - int PipeNum = state.dataSurface->SurfWinTDDPipeNum(SurfNum); - SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome; - } - Real64 CosInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2); - Real64 SunLitFract = state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2); + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { + // TH added 3/24/2010 while debugging CR 7872 + if (!state.dataSurface->Surface(SurfNum).ExtSolar && state.dataSurface->SurfWinOriginalClass(SurfNum) != SurfaceClass::TDD_Diffuser) + continue; + int const ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); + int SurfNum2 = SurfNum; + if (state.dataSurface->SurfWinOriginalClass(SurfNum) == SurfaceClass::TDD_Diffuser) { + int PipeNum = state.dataSurface->SurfWinTDDPipeNum(SurfNum); + SurfNum2 = state.dataDaylightingDevicesData->TDDPipe(PipeNum).Dome; + } + Real64 CosInc = state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2); + Real64 SunLitFract = state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum2); - //------------------------------------------------------------------------- - // EXTERIOR BEAM SOLAR RADIATION ABSORBED ON THE OUTSIDE OF OPAQUE SURFACES - //------------------------------------------------------------------------- + //------------------------------------------------------------------------- + // EXTERIOR BEAM SOLAR RADIATION ABSORBED ON THE OUTSIDE OF OPAQUE SURFACES + //------------------------------------------------------------------------- - if (SunLitFract > 0.0 && state.dataConstruction->Construct(ConstrNum).TransDiff <= 0.0) { - state.dataSurface->SurfOpaqAO(SurfNum) = state.dataConstruction->Construct(ConstrNum).OutsideAbsorpSolar * CosInc * SunLitFract; + if (SunLitFract > 0.0 && state.dataConstruction->Construct(ConstrNum).TransDiff <= 0.0) { + state.dataSurface->SurfOpaqAO(SurfNum) = state.dataConstruction->Construct(ConstrNum).OutsideAbsorpSolar * CosInc * SunLitFract; - // Note: movable insulation, if present, is accounted for in subr. InitIntSolarDistribution, - // where SurfQRadSWOutMvIns is calculated from SurfOpaqQRadSWOutAbs and insulation solar absorptance + // Note: movable insulation, if present, is accounted for in subr. InitIntSolarDistribution, + // where SurfQRadSWOutMvIns is calculated from SurfOpaqQRadSWOutAbs and insulation solar absorptance + } } } } @@ -8589,11 +8605,14 @@ void CalcInteriorSolarDistributionWCESimple(EnergyPlusData &state) using namespace MultiLayerOptics; for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurf = state.dataHeatBal->Zone(zoneNum).HTSurfaceFirst; - int const lastSurf = state.dataHeatBal->Zone(zoneNum).HTSurfaceLast; - for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { - state.dataSurface->SurfOpaqAI(surfNum) = 0.0; - state.dataSurface->SurfOpaqAO(surfNum) = 0.0; + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurf = thisSpace.HTSurfaceFirst; + int const lastSurf = thisSpace.HTSurfaceLast; + for (int surfNum = firstSurf; surfNum <= lastSurf; ++surfNum) { + state.dataSurface->SurfOpaqAI(surfNum) = 0.0; + state.dataSurface->SurfOpaqAO(surfNum) = 0.0; + } } } @@ -8660,8 +8679,8 @@ void CalcInteriorSolarDistributionWCESimple(EnergyPlusData &state) auto AbWinBeam = aLayer->getAbsorptanceLayer(Lay, Side::Front, ScatteringSimple::Direct, Theta, Phi) * window.OutProjSLFracMult(state.dataGlobal->HourOfDay); auto AbWinDiffFront = aLayer->getAbsorptanceLayer(Lay, Side::Front, ScatteringSimple::Diffuse, Theta, Phi); - // auto AbWinDiffBack = aLayer->getAbsorptanceLayer(Lay, Side::Back, ScatteringSimple::Diffuse, Theta, - // Phi); + // auto AbWinDiffBack = aLayer->getAbsorptanceLayer(Lay, Side::Back, ScatteringSimple::Diffuse, + // Theta, Phi); // Simon: This should not be multiplied with cosine of incident angle. This however gives same // results as BSDF and Winkelmann models. @@ -9495,631 +9514,642 @@ void WindowShadingManager(EnergyPlusData &state) int IConst; // Construction for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceFirst; - int const lastSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceLast; - for (int ISurf = firstSurfWin; ISurf <= lastSurfWin; ++ISurf) { - state.dataSurface->SurfWinExtIntShadePrevTS(ISurf) = state.dataSurface->SurfWinShadingFlag(ISurf); - - state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::NoShade; - state.dataSurface->SurfWinFracTimeShadingDeviceOn(ISurf) = 0.0; - if (state.dataSurface->SurfWinWindowModelType(ISurf) == WindowModel::EQL) { - int EQLNum = state.dataConstruction->Construct(state.dataSurface->Surface(ISurf).Construction).EQLConsPtr; - if (state.dataWindowEquivLayer->CFS(EQLNum).VBLayerPtr > 0) { - if (state.dataWindowEquivLayer->CFS(EQLNum).L(state.dataWindowEquivLayer->CFS(EQLNum).VBLayerPtr).CNTRL == - state.dataWindowEquivalentLayer->lscNONE) { - state.dataSurface->SurfWinSlatAngThisTSDeg(ISurf) = - state.dataWindowEquivLayer->CFS(EQLNum).L(state.dataWindowEquivLayer->CFS(EQLNum).VBLayerPtr).PHI_DEG; - } else { - state.dataSurface->SurfWinSlatAngThisTSDeg(ISurf) = 0.0; + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurfWin = thisSpace.WindowSurfaceFirst; + int const lastSurfWin = thisSpace.WindowSurfaceLast; + for (int ISurf = firstSurfWin; ISurf <= lastSurfWin; ++ISurf) { + state.dataSurface->SurfWinExtIntShadePrevTS(ISurf) = state.dataSurface->SurfWinShadingFlag(ISurf); + + state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::NoShade; + state.dataSurface->SurfWinFracTimeShadingDeviceOn(ISurf) = 0.0; + if (state.dataSurface->SurfWinWindowModelType(ISurf) == WindowModel::EQL) { + int EQLNum = state.dataConstruction->Construct(state.dataSurface->Surface(ISurf).Construction).EQLConsPtr; + if (state.dataWindowEquivLayer->CFS(EQLNum).VBLayerPtr > 0) { + if (state.dataWindowEquivLayer->CFS(EQLNum).L(state.dataWindowEquivLayer->CFS(EQLNum).VBLayerPtr).CNTRL == + state.dataWindowEquivalentLayer->lscNONE) { + state.dataSurface->SurfWinSlatAngThisTSDeg(ISurf) = + state.dataWindowEquivLayer->CFS(EQLNum).L(state.dataWindowEquivLayer->CFS(EQLNum).VBLayerPtr).PHI_DEG; + } else { + state.dataSurface->SurfWinSlatAngThisTSDeg(ISurf) = 0.0; + } } } - } - // Initialization of complex fenestration shading device - if (state.dataSurface->SurfWinWindowModelType(ISurf) == WindowModel::BSDF) { - auto &construction(state.dataConstruction->Construct(state.dataSurface->Surface(ISurf).Construction)); - auto &surface_window(state.dataSurface->SurfaceWindow(ISurf)); - int TotLayers = construction.TotLayers; - for (auto Lay = 1; Lay <= TotLayers; ++Lay) { - const int LayPtr = construction.LayerPoint(Lay); - auto &material(state.dataMaterial->Material(LayPtr)); - const bool isShading = material.Group == DataHeatBalance::MaterialGroup::ComplexWindowShade; - if (isShading && Lay == 1) { - state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::ExtShade; - } - if (isShading && Lay == TotLayers) { - state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::IntShade; - } - } - if (state.dataSurface->SurfWinShadingFlag(ISurf) == WinShadingType::IntShade) { + // Initialization of complex fenestration shading device + if (state.dataSurface->SurfWinWindowModelType(ISurf) == WindowModel::BSDF) { auto &construction(state.dataConstruction->Construct(state.dataSurface->Surface(ISurf).Construction)); - const int TotLay = construction.TotLayers; - int ShadingLayerPtr = construction.LayerPoint(TotLay); - ShadingLayerPtr = state.dataMaterial->Material(ShadingLayerPtr).ComplexShadePtr; - auto &complexShade = state.dataHeatBal->ComplexShade(ShadingLayerPtr); - auto TauShadeIR = complexShade.IRTransmittance; - auto EpsShadeIR = complexShade.BackEmissivity; - auto RhoShadeIR = max(0.0, 1.0 - TauShadeIR - EpsShadeIR); - // Get properties of glass next to inside shading layer - int GlassLayPtr = construction.LayerPoint(TotLay - 2); - auto EpsGlassIR = state.dataMaterial->Material(GlassLayPtr).AbsorpThermalBack; - auto RhoGlassIR = 1 - EpsGlassIR; - - auto EffShBlEmiss = EpsShadeIR * (1.0 + RhoGlassIR * TauShadeIR / (1.0 - RhoGlassIR * RhoShadeIR)); - surface_window.EffShBlindEmiss[0] = EffShBlEmiss; - auto EffGlEmiss = EpsGlassIR * TauShadeIR / (1.0 - RhoGlassIR * RhoShadeIR); - surface_window.EffGlassEmiss[0] = EffGlEmiss; - } - } - - if (state.dataSurface->Surface(ISurf).ExtBoundCond != ExternalEnvironment) continue; - if (!state.dataSurface->Surface(ISurf).HasShadeControl) { - continue; - } else { - // - } - - // Initialize switching factor (applicable only to switchable glazing) to unswitched - state.dataSurface->SurfWinSwitchingFactor(ISurf) = 0.0; - - IConst = state.dataSurface->Surface(ISurf).Construction; - // Vis trans at normal incidence of unswitched glass. Counting the GlazedFrac - if (IConst > 0) - state.dataSurface->SurfWinVisTransSelected(ISurf) = - POLYF(1.0, state.dataConstruction->Construct(IConst).TransVisBeamCoef) * state.dataSurface->SurfWinGlazedFrac(ISurf); - - // Window has shading control - // select the active window shading control and corresponding contructions - size_t indexWindowShadingControl = selectActiveWindowShadingControlIndex(state, ISurf); - if (!state.dataSurface->Surface(ISurf).windowShadingControlList.empty() && - indexWindowShadingControl <= state.dataSurface->Surface(ISurf).windowShadingControlList.size() - 1) { - state.dataSurface->Surface(ISurf).activeWindowShadingControl = - state.dataSurface->Surface(ISurf).windowShadingControlList[indexWindowShadingControl]; - } - state.dataSurface->Surface(ISurf).activeShadedConstructionPrev = state.dataSurface->Surface(ISurf).activeShadedConstruction; - if (!state.dataSurface->Surface(ISurf).shadedConstructionList.empty() && - indexWindowShadingControl <= state.dataSurface->Surface(ISurf).shadedConstructionList.size() - 1) { - state.dataSurface->Surface(ISurf).activeShadedConstruction = - state.dataSurface->Surface(ISurf).shadedConstructionList[indexWindowShadingControl]; - } - state.dataSurface->SurfWinActiveShadedConstruction(ISurf) = state.dataSurface->Surface(ISurf).activeShadedConstruction; - if (!state.dataSurface->Surface(ISurf).shadedStormWinConstructionList.empty() && - indexWindowShadingControl <= state.dataSurface->Surface(ISurf).shadedStormWinConstructionList.size() - 1) { - if (state.dataSurface->SurfWinStormWinFlag(ISurf) == 1) { - state.dataSurface->SurfWinActiveShadedConstruction(ISurf) = - state.dataSurface->Surface(ISurf).shadedStormWinConstructionList[indexWindowShadingControl]; - } - } - - int IShadingCtrl = state.dataSurface->Surface(ISurf).activeWindowShadingControl; - int IZone = state.dataSurface->Surface(ISurf).Zone; - // Setpoint for shading - Real64 SetPoint = state.dataSurface->WindowShadingControl(IShadingCtrl).SetPoint; // Control setpoint - Real64 SetPoint2 = state.dataSurface->WindowShadingControl(IShadingCtrl).SetPoint2; // Second control setpoint - - bool SchedAllowsControl = true; // True if control schedule is not specified or is specified and schedule value = 1 - int SchedulePtr = state.dataSurface->WindowShadingControl(IShadingCtrl).Schedule; - if (SchedulePtr != 0) { - if (state.dataSurface->WindowShadingControl(IShadingCtrl).ShadingControlIsScheduled && - GetCurrentScheduleValue(state, SchedulePtr) <= 0.0) - SchedAllowsControl = false; - } - - Real64 GlareControlIsActive = - (state.dataDaylightingData->ZoneDaylight(IZone).totRefPts > 0 && state.dataEnvrn->SunIsUp && - state.dataSurface->WindowShadingControl(IShadingCtrl).GlareControlIsActive); // True if glare control is active - - Real64 SolarOnWindow = 0.0; // Direct plus diffuse solar intensity on window (W/m2) - Real64 BeamSolarOnWindow = 0.0; // Direct solar intensity on window (W/m2) - Real64 HorizSolar = 0.0; // Horizontal direct plus diffuse solar intensity - if (state.dataEnvrn->SunIsUp) { - Real64 SkySolarOnWindow = - state.dataSolarShading->SurfAnisoSkyMult(ISurf) * state.dataEnvrn->DifSolarRad; // Sky diffuse solar intensity on window (W/m2) - BeamSolarOnWindow = state.dataEnvrn->BeamSolarRad * - state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, ISurf) * - state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, ISurf); - SolarOnWindow = - BeamSolarOnWindow + SkySolarOnWindow + state.dataEnvrn->GndSolarRad * state.dataSurface->Surface(ISurf).ViewFactorGround; - HorizSolar = state.dataEnvrn->BeamSolarRad * state.dataEnvrn->SOLCOS(3) + state.dataEnvrn->DifSolarRad; - } - - // Determine whether to deploy shading depending on type of control - - bool shadingOn = false; - bool shadingOffButGlareControlOn = false; - switch (state.dataSurface->WindowShadingControl(IShadingCtrl).shadingControlType) { - case WindowShadingControlType::AlwaysOn: // 'ALWAYSON' - shadingOn = true; - break; - case WindowShadingControlType::AlwaysOff: // 'ALWAYSOFF' - break; - case WindowShadingControlType::OnIfScheduled: // 'ONIFSCHEDULEALLOWS' - if (SchedAllowsControl) shadingOn = true; - break; - case WindowShadingControlType::HiSolar: // 'ONIFHIGHSOLARONWINDOW' - // ! Direct plus diffuse solar intensity on window - if (state.dataEnvrn->SunIsUp) { - if (SolarOnWindow > SetPoint && SchedAllowsControl) { - shadingOn = true; - } else if (GlareControlIsActive) { - shadingOffButGlareControlOn = true; + auto &surface_window(state.dataSurface->SurfaceWindow(ISurf)); + int TotLayers = construction.TotLayers; + for (auto Lay = 1; Lay <= TotLayers; ++Lay) { + const int LayPtr = construction.LayerPoint(Lay); + auto &material(state.dataMaterial->Material(LayPtr)); + const bool isShading = material.Group == DataHeatBalance::MaterialGroup::ComplexWindowShade; + if (isShading && Lay == 1) { + state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::ExtShade; + } + if (isShading && Lay == TotLayers) { + state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::IntShade; + } + } + if (state.dataSurface->SurfWinShadingFlag(ISurf) == WinShadingType::IntShade) { + auto &construction(state.dataConstruction->Construct(state.dataSurface->Surface(ISurf).Construction)); + const int TotLay = construction.TotLayers; + int ShadingLayerPtr = construction.LayerPoint(TotLay); + ShadingLayerPtr = state.dataMaterial->Material(ShadingLayerPtr).ComplexShadePtr; + auto &complexShade = state.dataHeatBal->ComplexShade(ShadingLayerPtr); + auto TauShadeIR = complexShade.IRTransmittance; + auto EpsShadeIR = complexShade.BackEmissivity; + auto RhoShadeIR = max(0.0, 1.0 - TauShadeIR - EpsShadeIR); + // Get properties of glass next to inside shading layer + int GlassLayPtr = construction.LayerPoint(TotLay - 2); + auto EpsGlassIR = state.dataMaterial->Material(GlassLayPtr).AbsorpThermalBack; + auto RhoGlassIR = 1 - EpsGlassIR; + + auto EffShBlEmiss = EpsShadeIR * (1.0 + RhoGlassIR * TauShadeIR / (1.0 - RhoGlassIR * RhoShadeIR)); + surface_window.EffShBlindEmiss[0] = EffShBlEmiss; + auto EffGlEmiss = EpsGlassIR * TauShadeIR / (1.0 - RhoGlassIR * RhoShadeIR); + surface_window.EffGlassEmiss[0] = EffGlEmiss; } } - break; - case WindowShadingControlType::HiHorzSolar: // 'ONIFHIGHHORIZONTALSOLAR' ! Direct plus diffuse exterior horizontal solar intensity - if (state.dataEnvrn->SunIsUp) { - if (HorizSolar > SetPoint && SchedAllowsControl) { - shadingOn = true; - } else if (GlareControlIsActive) { - shadingOffButGlareControlOn = true; + if (state.dataSurface->Surface(ISurf).ExtBoundCond != ExternalEnvironment) continue; + if (!state.dataSurface->Surface(ISurf).HasShadeControl) { + continue; + } else { + // + } + + // Initialize switching factor (applicable only to switchable glazing) to unswitched + state.dataSurface->SurfWinSwitchingFactor(ISurf) = 0.0; + + IConst = state.dataSurface->Surface(ISurf).Construction; + // Vis trans at normal incidence of unswitched glass. Counting the GlazedFrac + if (IConst > 0) + state.dataSurface->SurfWinVisTransSelected(ISurf) = + POLYF(1.0, state.dataConstruction->Construct(IConst).TransVisBeamCoef) * state.dataSurface->SurfWinGlazedFrac(ISurf); + + // Window has shading control + // select the active window shading control and corresponding contructions + size_t indexWindowShadingControl = selectActiveWindowShadingControlIndex(state, ISurf); + if (!state.dataSurface->Surface(ISurf).windowShadingControlList.empty() && + indexWindowShadingControl <= state.dataSurface->Surface(ISurf).windowShadingControlList.size() - 1) { + state.dataSurface->Surface(ISurf).activeWindowShadingControl = + state.dataSurface->Surface(ISurf).windowShadingControlList[indexWindowShadingControl]; + } + state.dataSurface->Surface(ISurf).activeShadedConstructionPrev = state.dataSurface->Surface(ISurf).activeShadedConstruction; + if (!state.dataSurface->Surface(ISurf).shadedConstructionList.empty() && + indexWindowShadingControl <= state.dataSurface->Surface(ISurf).shadedConstructionList.size() - 1) { + state.dataSurface->Surface(ISurf).activeShadedConstruction = + state.dataSurface->Surface(ISurf).shadedConstructionList[indexWindowShadingControl]; + } + state.dataSurface->SurfWinActiveShadedConstruction(ISurf) = state.dataSurface->Surface(ISurf).activeShadedConstruction; + if (!state.dataSurface->Surface(ISurf).shadedStormWinConstructionList.empty() && + indexWindowShadingControl <= state.dataSurface->Surface(ISurf).shadedStormWinConstructionList.size() - 1) { + if (state.dataSurface->SurfWinStormWinFlag(ISurf) == 1) { + state.dataSurface->SurfWinActiveShadedConstruction(ISurf) = + state.dataSurface->Surface(ISurf).shadedStormWinConstructionList[indexWindowShadingControl]; } } - break; - case WindowShadingControlType::HiOutAirTemp: // 'OnIfHighOutdoorAirTemperature' - if (state.dataSurface->SurfOutDryBulbTemp(ISurf) > SetPoint && SchedAllowsControl) { - shadingOn = true; - } else if (GlareControlIsActive) { - shadingOffButGlareControlOn = true; - } - break; + int IShadingCtrl = state.dataSurface->Surface(ISurf).activeWindowShadingControl; + int IZone = state.dataSurface->Surface(ISurf).Zone; + // Setpoint for shading + Real64 SetPoint = state.dataSurface->WindowShadingControl(IShadingCtrl).SetPoint; // Control setpoint + Real64 SetPoint2 = state.dataSurface->WindowShadingControl(IShadingCtrl).SetPoint2; // Second control setpoint - case WindowShadingControlType::HiZoneAirTemp: // 'OnIfHighZoneAirTemperature' ! Previous time step zone air temperature - if (state.dataHeatBalFanSys->MAT(IZone) > SetPoint && SchedAllowsControl) { - shadingOn = true; - } else if (GlareControlIsActive) { - shadingOffButGlareControlOn = true; + bool SchedAllowsControl = true; // True if control schedule is not specified or is specified and schedule value = 1 + int SchedulePtr = state.dataSurface->WindowShadingControl(IShadingCtrl).Schedule; + if (SchedulePtr != 0) { + if (state.dataSurface->WindowShadingControl(IShadingCtrl).ShadingControlIsScheduled && + GetCurrentScheduleValue(state, SchedulePtr) <= 0.0) + SchedAllowsControl = false; } - break; - case WindowShadingControlType::OnHiOutTemp_HiSolarWindow: // 'OnIfHighOutdoorAirTempAndHighSolarOnWindow' ! Outside air temp and solar on - // window + Real64 GlareControlIsActive = + (state.dataDaylightingData->ZoneDaylight(IZone).totRefPts > 0 && state.dataEnvrn->SunIsUp && + state.dataSurface->WindowShadingControl(IShadingCtrl).GlareControlIsActive); // True if glare control is active + + Real64 SolarOnWindow = 0.0; // Direct plus diffuse solar intensity on window (W/m2) + Real64 BeamSolarOnWindow = 0.0; // Direct solar intensity on window (W/m2) + Real64 HorizSolar = 0.0; // Horizontal direct plus diffuse solar intensity if (state.dataEnvrn->SunIsUp) { - if (state.dataSurface->SurfOutDryBulbTemp(ISurf) > SetPoint && SolarOnWindow > SetPoint2 && SchedAllowsControl) { - shadingOn = true; - } else if (GlareControlIsActive) { - shadingOffButGlareControlOn = true; + Real64 SkySolarOnWindow = state.dataSolarShading->SurfAnisoSkyMult(ISurf) * + state.dataEnvrn->DifSolarRad; // Sky diffuse solar intensity on window (W/m2) + BeamSolarOnWindow = state.dataEnvrn->BeamSolarRad * + state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, ISurf) * + state.dataHeatBal->SurfSunlitFrac(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, ISurf); + SolarOnWindow = + BeamSolarOnWindow + SkySolarOnWindow + state.dataEnvrn->GndSolarRad * state.dataSurface->Surface(ISurf).ViewFactorGround; + HorizSolar = state.dataEnvrn->BeamSolarRad * state.dataEnvrn->SOLCOS(3) + state.dataEnvrn->DifSolarRad; + } + + // Determine whether to deploy shading depending on type of control + auto &thisIZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(IZone); + + bool shadingOn = false; + bool shadingOffButGlareControlOn = false; + switch (state.dataSurface->WindowShadingControl(IShadingCtrl).shadingControlType) { + case WindowShadingControlType::AlwaysOn: // 'ALWAYSON' + shadingOn = true; + break; + case WindowShadingControlType::AlwaysOff: // 'ALWAYSOFF' + break; + case WindowShadingControlType::OnIfScheduled: // 'ONIFSCHEDULEALLOWS' + if (SchedAllowsControl) shadingOn = true; + break; + case WindowShadingControlType::HiSolar: // 'ONIFHIGHSOLARONWINDOW' + // ! Direct plus diffuse solar intensity on window + if (state.dataEnvrn->SunIsUp) { + if (SolarOnWindow > SetPoint && SchedAllowsControl) { + shadingOn = true; + } else if (GlareControlIsActive) { + shadingOffButGlareControlOn = true; + } } - } - break; + break; - case WindowShadingControlType::OnHiOutTemp_HiHorzSolar: // 'OnIfHighOutdoorAirTempAndHighHorizontalSolar' ! Outside air temp and - // horizontal solar - if (state.dataEnvrn->SunIsUp) { - if (state.dataSurface->SurfOutDryBulbTemp(ISurf) > SetPoint && HorizSolar > SetPoint2 && SchedAllowsControl) { - shadingOn = true; - } else if (GlareControlIsActive) { - shadingOffButGlareControlOn = true; + case WindowShadingControlType::HiHorzSolar: // 'ONIFHIGHHORIZONTALSOLAR' ! Direct plus diffuse exterior horizontal solar intensity + if (state.dataEnvrn->SunIsUp) { + if (HorizSolar > SetPoint && SchedAllowsControl) { + shadingOn = true; + } else if (GlareControlIsActive) { + shadingOffButGlareControlOn = true; + } } - } - break; + break; - case WindowShadingControlType::OnHiZoneTemp_HiSolarWindow: // 'ONIFHIGHZONEAIRTEMPANDHIGHSOLARONWINDOW' ! Zone air temp and solar on - // window - if (state.dataEnvrn->SunIsUp) { - if (state.dataHeatBalFanSys->MAT(IZone) > SetPoint && SolarOnWindow > SetPoint2 && SchedAllowsControl) { + case WindowShadingControlType::HiOutAirTemp: // 'OnIfHighOutdoorAirTemperature' + if (state.dataSurface->SurfOutDryBulbTemp(ISurf) > SetPoint && SchedAllowsControl) { shadingOn = true; } else if (GlareControlIsActive) { shadingOffButGlareControlOn = true; } - } - break; + break; - case WindowShadingControlType::OnHiZoneTemp_HiHorzSolar: // 'ONIFHIGHZONEAIRTEMPANDHIGHHORIZONTALSOLAR' ! Zone air temp and horizontal - // solar - if (state.dataEnvrn->SunIsUp) { - if (state.dataHeatBalFanSys->MAT(IZone) > SetPoint && HorizSolar > SetPoint2 && SchedAllowsControl) { + case WindowShadingControlType::HiZoneAirTemp: // 'OnIfHighZoneAirTemperature' ! Previous time step zone air temperature + if (thisIZoneHB.MAT > SetPoint && SchedAllowsControl) { shadingOn = true; } else if (GlareControlIsActive) { shadingOffButGlareControlOn = true; } - } - break; + break; - case WindowShadingControlType::HiZoneCooling: - // 'ONIFHIGHZONECOOLING' ! Previous time step zone sensible cooling rate [W] - // In the following, the check on BeginSimFlag is needed since SNLoadCoolRate (and SNLoadHeatRate, - // used in other CASEs) are not allocated at this point for the first time step of the simulation. - if (!state.dataGlobal->BeginSimFlag) { - if (state.dataHeatBal->ZoneSNLoadCoolRate(IZone) > SetPoint && SchedAllowsControl) { - shadingOn = true; - } else if (GlareControlIsActive) { - shadingOffButGlareControlOn = true; + case WindowShadingControlType::OnHiOutTemp_HiSolarWindow: // 'OnIfHighOutdoorAirTempAndHighSolarOnWindow' ! Outside air temp and + // solar on window + if (state.dataEnvrn->SunIsUp) { + if (state.dataSurface->SurfOutDryBulbTemp(ISurf) > SetPoint && SolarOnWindow > SetPoint2 && SchedAllowsControl) { + shadingOn = true; + } else if (GlareControlIsActive) { + shadingOffButGlareControlOn = true; + } } - } - break; + break; - case WindowShadingControlType::HiGlare: - // 'ONIFHIGHGLARE' ! Daylight glare index at first reference point in the zone. - // This type of shading control is done in DayltgInteriorIllum. Glare control is not affected - // by control schedule. - if (state.dataEnvrn->SunIsUp) { - shadingOffButGlareControlOn = true; - } - break; + case WindowShadingControlType::OnHiOutTemp_HiHorzSolar: // 'OnIfHighOutdoorAirTempAndHighHorizontalSolar' ! Outside air temp and + // horizontal solar + if (state.dataEnvrn->SunIsUp) { + if (state.dataSurface->SurfOutDryBulbTemp(ISurf) > SetPoint && HorizSolar > SetPoint2 && SchedAllowsControl) { + shadingOn = true; + } else if (GlareControlIsActive) { + shadingOffButGlareControlOn = true; + } + } + break; - case WindowShadingControlType::MeetDaylIlumSetp: - // 'MEETDAYLIGHTILLUMINANCESETPOINT') ! Daylight illuminance test is done in DayltgInteriorIllum - // Only switchable glazing does daylight illuminance control - if (state.dataEnvrn->SunIsUp && SchedAllowsControl) { - shadingOffButGlareControlOn = true; - } - break; + case WindowShadingControlType::OnHiZoneTemp_HiSolarWindow: // 'ONIFHIGHZONEAIRTEMPANDHIGHSOLARONWINDOW' ! Zone air temp and solar on + // window + if (state.dataEnvrn->SunIsUp) { + if (thisIZoneHB.MAT > SetPoint && SolarOnWindow > SetPoint2 && SchedAllowsControl) { + shadingOn = true; + } else if (GlareControlIsActive) { + shadingOffButGlareControlOn = true; + } + } + break; - case WindowShadingControlType::HiSolar_HiLumin_OffMidNight: - // 'OnIfHighSolarOrHighLuminanceTillMidnight' - // if shade is already on, then keep it on until midnight, otherwise check thresholds - if (SchedAllowsControl && IS_SHADED(state.dataSurface->SurfWinExtIntShadePrevTS(ISurf))) { - shadingOn = true; - } else if (state.dataEnvrn->SunIsUp && SchedAllowsControl) { - if (SolarOnWindow > SetPoint) { - shadingOn = true; - } else { - // pass to DayltgInteriorIllum to check for luminance - shadingOn = false; + case WindowShadingControlType::OnHiZoneTemp_HiHorzSolar: // 'ONIFHIGHZONEAIRTEMPANDHIGHHORIZONTALSOLAR' ! Zone air temp and + // horizontal solar + if (state.dataEnvrn->SunIsUp) { + if (thisIZoneHB.MAT > SetPoint && HorizSolar > SetPoint2 && SchedAllowsControl) { + shadingOn = true; + } else if (GlareControlIsActive) { + shadingOffButGlareControlOn = true; + } + } + break; + + case WindowShadingControlType::HiZoneCooling: + // 'ONIFHIGHZONECOOLING' ! Previous time step zone sensible cooling rate [W] + // In the following, the check on BeginSimFlag is needed since SNLoadCoolRate (and SNLoadHeatRate, + // used in other CASEs) are not allocated at this point for the first time step of the simulation. + if (!state.dataGlobal->BeginSimFlag) { + if (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(IZone).ZoneSNLoadCoolRate > SetPoint && SchedAllowsControl) { + shadingOn = true; + } else if (GlareControlIsActive) { + shadingOffButGlareControlOn = true; + } + } + break; + + case WindowShadingControlType::HiGlare: + // 'ONIFHIGHGLARE' ! Daylight glare index at first reference point in the zone. + // This type of shading control is done in DayltgInteriorIllum. Glare control is not affected + // by control schedule. + if (state.dataEnvrn->SunIsUp) { shadingOffButGlareControlOn = true; } - } - // if it is the beginning of the day, then shades off - if (state.dataGlobal->BeginDayFlag) { - shadingOn = false; - shadingOffButGlareControlOn = false; - } - break; + break; - case WindowShadingControlType::HiSolar_HiLumin_OffSunset: - // 'OnIfHighSolarOrHighLuminanceTillSunset' - // if shade is already on, then keep it on until sunset, otherwise check thresholds - if (SchedAllowsControl && IS_SHADED(state.dataSurface->SurfWinExtIntShadePrevTS(ISurf))) { - shadingOn = true; - } else if (state.dataEnvrn->SunIsUp && SchedAllowsControl) { - if (SolarOnWindow > SetPoint) { + case WindowShadingControlType::MeetDaylIlumSetp: + // 'MEETDAYLIGHTILLUMINANCESETPOINT') ! Daylight illuminance test is done in DayltgInteriorIllum + // Only switchable glazing does daylight illuminance control + if (state.dataEnvrn->SunIsUp && SchedAllowsControl) { + shadingOffButGlareControlOn = true; + } + break; + + case WindowShadingControlType::HiSolar_HiLumin_OffMidNight: + // 'OnIfHighSolarOrHighLuminanceTillMidnight' + // if shade is already on, then keep it on until midnight, otherwise check thresholds + if (SchedAllowsControl && IS_SHADED(state.dataSurface->SurfWinExtIntShadePrevTS(ISurf))) { shadingOn = true; - } else { - // pass to DayltgInteriorIllum to check for luminance + } else if (state.dataEnvrn->SunIsUp && SchedAllowsControl) { + if (SolarOnWindow > SetPoint) { + shadingOn = true; + } else { + // pass to DayltgInteriorIllum to check for luminance + shadingOn = false; + shadingOffButGlareControlOn = true; + } + } + // if it is the beginning of the day, then shades off + if (state.dataGlobal->BeginDayFlag) { shadingOn = false; - shadingOffButGlareControlOn = true; + shadingOffButGlareControlOn = false; } - } - // if sunset, then shades off - if (!state.dataEnvrn->SunIsUp) { - shadingOn = false; - shadingOffButGlareControlOn = false; - } - break; + break; - case WindowShadingControlType::HiSolar_HiLumin_OffNextMorning: - // 'OnIfHighSolarOrHighLuminanceTillNextMorning' - // if shade is already on, then keep it on until next day when sun is up, otherwise check thresholds - if (SchedAllowsControl && IS_SHADED(state.dataSurface->SurfWinExtIntShadePrevTS(ISurf))) { - shadingOn = true; - } else if (state.dataEnvrn->SunIsUp && SchedAllowsControl) { - if (SolarOnWindow > SetPoint) { + case WindowShadingControlType::HiSolar_HiLumin_OffSunset: + // 'OnIfHighSolarOrHighLuminanceTillSunset' + // if shade is already on, then keep it on until sunset, otherwise check thresholds + if (SchedAllowsControl && IS_SHADED(state.dataSurface->SurfWinExtIntShadePrevTS(ISurf))) { shadingOn = true; - } else { - // pass to DayltgInteriorIllum to check for luminance + } else if (state.dataEnvrn->SunIsUp && SchedAllowsControl) { + if (SolarOnWindow > SetPoint) { + shadingOn = true; + } else { + // pass to DayltgInteriorIllum to check for luminance + shadingOn = false; + shadingOffButGlareControlOn = true; + } + } + // if sunset, then shades off + if (!state.dataEnvrn->SunIsUp) { shadingOn = false; - shadingOffButGlareControlOn = true; + shadingOffButGlareControlOn = false; } - } - // if next morning (identified by sun is not up in previous time step and is up now), then shades off - if (!state.dataEnvrn->SunIsUpPrevTS && state.dataEnvrn->SunIsUp) { - shadingOn = false; - shadingOffButGlareControlOn = false; - } - break; + break; - case WindowShadingControlType::OnNightLoOutTemp_OffDay: // 'OnNightIfLowOutdoorTempAndOffDay' - if (!state.dataEnvrn->SunIsUp && state.dataSurface->SurfOutDryBulbTemp(ISurf) < SetPoint && SchedAllowsControl) { - shadingOn = true; - } else if (GlareControlIsActive) { - shadingOffButGlareControlOn = true; - } - break; + case WindowShadingControlType::HiSolar_HiLumin_OffNextMorning: + // 'OnIfHighSolarOrHighLuminanceTillNextMorning' + // if shade is already on, then keep it on until next day when sun is up, otherwise check thresholds + if (SchedAllowsControl && IS_SHADED(state.dataSurface->SurfWinExtIntShadePrevTS(ISurf))) { + shadingOn = true; + } else if (state.dataEnvrn->SunIsUp && SchedAllowsControl) { + if (SolarOnWindow > SetPoint) { + shadingOn = true; + } else { + // pass to DayltgInteriorIllum to check for luminance + shadingOn = false; + shadingOffButGlareControlOn = true; + } + } + // if next morning (identified by sun is not up in previous time step and is up now), then shades off + if (!state.dataEnvrn->SunIsUpPrevTS && state.dataEnvrn->SunIsUp) { + shadingOn = false; + shadingOffButGlareControlOn = false; + } + break; - case WindowShadingControlType::OnNightLoInTemp_OffDay: // 'OnNightIfLowInsideTempAndOffDay') - if (!state.dataEnvrn->SunIsUp && state.dataHeatBalFanSys->MAT(IZone) < SetPoint && SchedAllowsControl) { - shadingOn = true; - } else if (GlareControlIsActive) { - shadingOffButGlareControlOn = true; - } - break; + case WindowShadingControlType::OnNightLoOutTemp_OffDay: // 'OnNightIfLowOutdoorTempAndOffDay' + if (!state.dataEnvrn->SunIsUp && state.dataSurface->SurfOutDryBulbTemp(ISurf) < SetPoint && SchedAllowsControl) { + shadingOn = true; + } else if (GlareControlIsActive) { + shadingOffButGlareControlOn = true; + } + break; - case WindowShadingControlType::OnNightIfHeating_OffDay: // 'OnNightIfHeatingAndOffDay' - if (!state.dataGlobal->BeginSimFlag) { - if (!state.dataEnvrn->SunIsUp && state.dataHeatBal->ZoneSNLoadHeatRate(IZone) > SetPoint && SchedAllowsControl) { + case WindowShadingControlType::OnNightLoInTemp_OffDay: // 'OnNightIfLowInsideTempAndOffDay') + if (!state.dataEnvrn->SunIsUp && thisIZoneHB.MAT < SetPoint && SchedAllowsControl) { shadingOn = true; } else if (GlareControlIsActive) { shadingOffButGlareControlOn = true; } - } - break; + break; - case WindowShadingControlType::OnNightLoOutTemp_OnDayCooling: // 'OnNightIfLowOutdoorTempAndOnDayIfCooling' - if (!state.dataGlobal->BeginSimFlag) { - if (!state.dataEnvrn->SunIsUp) { // Night - if (state.dataSurface->SurfOutDryBulbTemp(ISurf) < SetPoint && SchedAllowsControl) shadingOn = true; - } else { // Day - if (state.dataHeatBal->ZoneSNLoadCoolRate(IZone) > 0.0 && SchedAllowsControl) { + case WindowShadingControlType::OnNightIfHeating_OffDay: // 'OnNightIfHeatingAndOffDay' + if (!state.dataGlobal->BeginSimFlag) { + if (!state.dataEnvrn->SunIsUp && state.dataZoneEnergyDemand->ZoneSysEnergyDemand(IZone).ZoneSNLoadHeatRate > SetPoint && + SchedAllowsControl) { shadingOn = true; } else if (GlareControlIsActive) { shadingOffButGlareControlOn = true; } } - } - break; + break; - case WindowShadingControlType::OnNightIfHeating_OnDayCooling: // 'OnNightIfHeatingAndOnDayIfCooling' - if (!state.dataGlobal->BeginSimFlag) { - if (!state.dataEnvrn->SunIsUp) { // Night - if (state.dataHeatBal->ZoneSNLoadHeatRate(IZone) > SetPoint && SchedAllowsControl) shadingOn = true; - } else { // Day - if (state.dataHeatBal->ZoneSNLoadCoolRate(IZone) > 0.0 && SchedAllowsControl) { - shadingOn = true; + case WindowShadingControlType::OnNightLoOutTemp_OnDayCooling: // 'OnNightIfLowOutdoorTempAndOnDayIfCooling' + if (!state.dataGlobal->BeginSimFlag) { + if (!state.dataEnvrn->SunIsUp) { // Night + if (state.dataSurface->SurfOutDryBulbTemp(ISurf) < SetPoint && SchedAllowsControl) shadingOn = true; + } else { // Day + if (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(IZone).ZoneSNLoadCoolRate > 0.0 && SchedAllowsControl) { + shadingOn = true; + } else if (GlareControlIsActive) { + shadingOffButGlareControlOn = true; + } + } + } + break; + + case WindowShadingControlType::OnNightIfHeating_OnDayCooling: // 'OnNightIfHeatingAndOnDayIfCooling' + if (!state.dataGlobal->BeginSimFlag) { + if (!state.dataEnvrn->SunIsUp) { // Night + if (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(IZone).ZoneSNLoadHeatRate > SetPoint && SchedAllowsControl) + shadingOn = true; + } else { // Day + if (state.dataZoneEnergyDemand->ZoneSysEnergyDemand(IZone).ZoneSNLoadCoolRate > 0.0 && SchedAllowsControl) { + shadingOn = true; + } else if (GlareControlIsActive) { + shadingOffButGlareControlOn = true; + } + } + } + break; + + case WindowShadingControlType::OffNight_OnDay_HiSolarWindow: // 'OffNightAndOnDayIfCoolingAndHighSolarOnWindow' + if (!state.dataGlobal->BeginSimFlag) { + if (state.dataEnvrn->SunIsUp && state.dataZoneEnergyDemand->ZoneSysEnergyDemand(IZone).ZoneSNLoadCoolRate > 0.0 && + SchedAllowsControl) { + if (SolarOnWindow > SetPoint) shadingOn = true; } else if (GlareControlIsActive) { shadingOffButGlareControlOn = true; } } - } - break; + break; - case WindowShadingControlType::OffNight_OnDay_HiSolarWindow: // 'OffNightAndOnDayIfCoolingAndHighSolarOnWindow' - if (!state.dataGlobal->BeginSimFlag) { - if (state.dataEnvrn->SunIsUp && state.dataHeatBal->ZoneSNLoadCoolRate(IZone) > 0.0 && SchedAllowsControl) { - if (SolarOnWindow > SetPoint) shadingOn = true; - } else if (GlareControlIsActive) { - shadingOffButGlareControlOn = true; + case WindowShadingControlType::OnNight_OnDay_HiSolarWindow: // 'OnNightAndOnDayIfCoolingAndHighSolarOnWindow' + if (!state.dataGlobal->BeginSimFlag) { + if (state.dataEnvrn->SunIsUp && state.dataZoneEnergyDemand->ZoneSysEnergyDemand(IZone).ZoneSNLoadCoolRate > 0.0 && + SchedAllowsControl) { + if (SolarOnWindow > SetPoint) shadingOn = true; + } else if (!state.dataEnvrn->SunIsUp && SchedAllowsControl) { + shadingOn = true; + } else if (GlareControlIsActive) { + shadingOffButGlareControlOn = true; + } } - } - break; - - case WindowShadingControlType::OnNight_OnDay_HiSolarWindow: // 'OnNightAndOnDayIfCoolingAndHighSolarOnWindow' - if (!state.dataGlobal->BeginSimFlag) { - if (state.dataEnvrn->SunIsUp && state.dataHeatBal->ZoneSNLoadCoolRate(IZone) > 0.0 && SchedAllowsControl) { - if (SolarOnWindow > SetPoint) shadingOn = true; - } else if (!state.dataEnvrn->SunIsUp && SchedAllowsControl) { - shadingOn = true; - } else if (GlareControlIsActive) { - shadingOffButGlareControlOn = true; + break; + default: + ShowWarningError(state, "Invalid Selection of Window Shading Control Type for Surface " + state.dataSurface->Surface(ISurf).Name); + } + + WinShadingType ShType = state.dataSurface->WindowShadingControl(IShadingCtrl).ShadingType; + + state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::ShadeOff; // Initialize shading flag to off + + if (IS_SHADED(ShType)) { + if (shadingOn) { + state.dataSurface->SurfWinShadingFlag(ISurf) = ShType; + } else if (shadingOffButGlareControlOn) { + if (ShType == WinShadingType::SwitchableGlazing) + state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::GlassConditionallyLightened; + else if (ShType == WinShadingType::IntShade) + state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::IntShadeConditionallyOff; + else if (ShType == WinShadingType::ExtShade) + state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::ExtShadeConditionallyOff; + else if (ShType == WinShadingType::IntBlind) + state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::IntBlindConditionallyOff; + else if (ShType == WinShadingType::ExtBlind) + state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::ExtBlindConditionallyOff; + else if (ShType == WinShadingType::BGShade) + state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::BGShadeConditionallyOff; + else if (ShType == WinShadingType::BGBlind) + state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::BGBlindConditionallyOff; } } - break; - default: - ShowWarningError(state, "Invalid Selection of Window Shading Control Type for Surface " + state.dataSurface->Surface(ISurf).Name); - } - - WinShadingType ShType = state.dataSurface->WindowShadingControl(IShadingCtrl).ShadingType; - - state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::ShadeOff; // Initialize shading flag to off - - if (IS_SHADED(ShType)) { - if (shadingOn) { - state.dataSurface->SurfWinShadingFlag(ISurf) = ShType; - } else if (shadingOffButGlareControlOn) { - if (ShType == WinShadingType::SwitchableGlazing) - state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::GlassConditionallyLightened; - else if (ShType == WinShadingType::IntShade) - state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::IntShadeConditionallyOff; - else if (ShType == WinShadingType::ExtShade) - state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::ExtShadeConditionallyOff; - else if (ShType == WinShadingType::IntBlind) - state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::IntBlindConditionallyOff; - else if (ShType == WinShadingType::ExtBlind) - state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::ExtBlindConditionallyOff; - else if (ShType == WinShadingType::BGShade) - state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::BGShadeConditionallyOff; - else if (ShType == WinShadingType::BGBlind) - state.dataSurface->SurfWinShadingFlag(ISurf) = WinShadingType::BGBlindConditionallyOff; - } - } - - // Set switching factor to fully switched if ShadingFlag = 2 - if (state.dataSurface->SurfWinShadingFlag(ISurf) == WinShadingType::SwitchableGlazing) { - state.dataSurface->SurfWinSwitchingFactor(ISurf) = 1.0; - - // Added TH 1/20/2010 - // Vis trans at normal incidence of fully switched glass - IConst = state.dataSurface->Surface(ISurf).activeShadedConstruction; - state.dataSurface->SurfWinVisTransSelected(ISurf) = - POLYF(1.0, state.dataConstruction->Construct(IConst).TransVisBeamCoef) * state.dataSurface->SurfWinGlazedFrac(ISurf); - } - - // Slat angle control for blinds - - state.dataSurface->SurfWinSlatAngThisTS(ISurf) = 0.0; - state.dataSurface->SurfWinSlatAngThisTSDeg(ISurf) = 0.0; - state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = false; - if (ANY_BLIND(state.dataSurface->SurfWinShadingFlag(ISurf)) || - state.dataSurface->SurfWinShadingFlag(ISurf) == WinShadingType::IntBlindConditionallyOff || - state.dataSurface->SurfWinShadingFlag(ISurf) == WinShadingType::ExtBlindConditionallyOff || - state.dataSurface->SurfWinShadingFlag(ISurf) == WinShadingType::BGBlindConditionallyOff) { - // Blind in place or may be in place due to glare control - int BlNum = state.dataSurface->SurfWinBlindNumber(ISurf); - if (BlNum > 0) { - Real64 InputSlatAngle = state.dataHeatBal->Blind(BlNum).SlatAngle * - DataGlobalConstants::DegToRadians; // Slat angle of associated Material:WindowBlind (rad) - Real64 ProfAng; // Solar profile angle (rad) - Real64 SlatAng; // Slat angle this time step (rad) - Real64 PermeabilityA; // Intermediate variables in blind permeability calc - Real64 PermeabilityB; - Real64 ThetaBase; // Intermediate slat angle variable (rad) - Real64 ThetaBlock1; // Slat angles that just block beam solar (rad) - Real64 ThetaBlock2; - - DaylightingManager::ProfileAngle(state, - ISurf, - state.dataEnvrn->SOLCOS, - state.dataHeatBal->Blind(BlNum).SlatOrientation, - state.dataSurface->SurfWinProfileAng(ISurf)); - ProfAng = state.dataSurface->SurfWinProfileAng(ISurf); - if (ProfAng > DataGlobalConstants::PiOvr2 || ProfAng < -DataGlobalConstants::PiOvr2) { - ProfAng = min(max(ProfAng, -DataGlobalConstants::PiOvr2), DataGlobalConstants::PiOvr2); - } - int ProfAngIndex = int((ProfAng + DataGlobalConstants::PiOvr2) / DeltaProfAng) + 1; - state.dataSurface->SurfWinProfAngIndex(ISurf) = ProfAngIndex; - state.dataSurface->SurfWinProfAngInterpFac(ISurf) = - (ProfAng + DataGlobalConstants::PiOvr2 - (ProfAngIndex - 1) * DeltaProfAng) / DeltaProfAng; - if (state.dataHeatBal->Blind(BlNum).SlatWidth > state.dataHeatBal->Blind(BlNum).SlatSeparation && BeamSolarOnWindow > 0.0) { + // Set switching factor to fully switched if ShadingFlag = 2 + if (state.dataSurface->SurfWinShadingFlag(ISurf) == WinShadingType::SwitchableGlazing) { + state.dataSurface->SurfWinSwitchingFactor(ISurf) = 1.0; + + // Added TH 1/20/2010 + // Vis trans at normal incidence of fully switched glass + IConst = state.dataSurface->Surface(ISurf).activeShadedConstruction; + state.dataSurface->SurfWinVisTransSelected(ISurf) = + POLYF(1.0, state.dataConstruction->Construct(IConst).TransVisBeamCoef) * state.dataSurface->SurfWinGlazedFrac(ISurf); + } + + // Slat angle control for blinds + + state.dataSurface->SurfWinSlatAngThisTS(ISurf) = 0.0; + state.dataSurface->SurfWinSlatAngThisTSDeg(ISurf) = 0.0; + state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = false; + if (ANY_BLIND(state.dataSurface->SurfWinShadingFlag(ISurf)) || + state.dataSurface->SurfWinShadingFlag(ISurf) == WinShadingType::IntBlindConditionallyOff || + state.dataSurface->SurfWinShadingFlag(ISurf) == WinShadingType::ExtBlindConditionallyOff || + state.dataSurface->SurfWinShadingFlag(ISurf) == WinShadingType::BGBlindConditionallyOff) { + // Blind in place or may be in place due to glare control + int BlNum = state.dataSurface->SurfWinBlindNumber(ISurf); + if (BlNum > 0) { + Real64 InputSlatAngle = state.dataHeatBal->Blind(BlNum).SlatAngle * + DataGlobalConstants::DegToRadians; // Slat angle of associated Material:WindowBlind (rad) + Real64 ProfAng; // Solar profile angle (rad) + Real64 SlatAng; // Slat angle this time step (rad) + Real64 PermeabilityA; // Intermediate variables in blind permeability calc + Real64 PermeabilityB; + Real64 ThetaBase; // Intermediate slat angle variable (rad) + Real64 ThetaBlock1; // Slat angles that just block beam solar (rad) + Real64 ThetaBlock2; + + DaylightingManager::ProfileAngle(state, + ISurf, + state.dataEnvrn->SOLCOS, + state.dataHeatBal->Blind(BlNum).SlatOrientation, + state.dataSurface->SurfWinProfileAng(ISurf)); ProfAng = state.dataSurface->SurfWinProfileAng(ISurf); - Real64 ThetaBase = - std::acos(std::cos(ProfAng) * state.dataHeatBal->Blind(BlNum).SlatSeparation / state.dataHeatBal->Blind(BlNum).SlatWidth); - // There are two solutions for the slat angle that just blocks beam radiation - ThetaBlock1 = ProfAng + ThetaBase; - ThetaBlock2 = ProfAng + DataGlobalConstants::Pi - ThetaBase; - state.dataSolarShading->ThetaSmall = min(ThetaBlock1, ThetaBlock2); - state.dataSolarShading->ThetaBig = max(ThetaBlock1, ThetaBlock2); - state.dataSolarShading->ThetaMin = state.dataHeatBal->Blind(BlNum).MinSlatAngle * DataGlobalConstants::DegToRadians; - state.dataSolarShading->ThetaMax = state.dataHeatBal->Blind(BlNum).MaxSlatAngle * DataGlobalConstants::DegToRadians; - } + if (ProfAng > DataGlobalConstants::PiOvr2 || ProfAng < -DataGlobalConstants::PiOvr2) { + ProfAng = min(max(ProfAng, -DataGlobalConstants::PiOvr2), DataGlobalConstants::PiOvr2); + } + int ProfAngIndex = int((ProfAng + DataGlobalConstants::PiOvr2) / DeltaProfAng) + 1; + state.dataSurface->SurfWinProfAngIndex(ISurf) = ProfAngIndex; + state.dataSurface->SurfWinProfAngInterpFac(ISurf) = + (ProfAng + DataGlobalConstants::PiOvr2 - (ProfAngIndex - 1) * DeltaProfAng) / DeltaProfAng; - // TH 5/20/2010, CR 8064: Slat Width <= Slat Separation - if (state.dataHeatBal->Blind(BlNum).SlatWidth <= state.dataHeatBal->Blind(BlNum).SlatSeparation && BeamSolarOnWindow > 0.0) { - if (state.dataSurface->WindowShadingControl(IShadingCtrl).slatAngleControl == SlatAngleControl::BlockBeamSolar) { + if (state.dataHeatBal->Blind(BlNum).SlatWidth > state.dataHeatBal->Blind(BlNum).SlatSeparation && BeamSolarOnWindow > 0.0) { ProfAng = state.dataSurface->SurfWinProfileAng(ISurf); - if (std::abs(std::cos(ProfAng) * state.dataHeatBal->Blind(BlNum).SlatSeparation / - state.dataHeatBal->Blind(BlNum).SlatWidth) <= 1.0) { - // set to block 100% of beam solar, not necessarily to block maximum solar (beam + diffuse) - ThetaBase = std::acos(std::cos(ProfAng) * state.dataHeatBal->Blind(BlNum).SlatSeparation / - state.dataHeatBal->Blind(BlNum).SlatWidth); - state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true; - } else { - // cannot block 100% of beam solar, turn slats to be perpendicular to sun beam to block maximal beam solar - ThetaBase = 0.0; - } - + Real64 ThetaBase = std::acos(std::cos(ProfAng) * state.dataHeatBal->Blind(BlNum).SlatSeparation / + state.dataHeatBal->Blind(BlNum).SlatWidth); // There are two solutions for the slat angle that just blocks beam radiation ThetaBlock1 = ProfAng + ThetaBase; - ThetaBlock2 = ProfAng - ThetaBase + DataGlobalConstants::Pi; - + ThetaBlock2 = ProfAng + DataGlobalConstants::Pi - ThetaBase; state.dataSolarShading->ThetaSmall = min(ThetaBlock1, ThetaBlock2); state.dataSolarShading->ThetaBig = max(ThetaBlock1, ThetaBlock2); state.dataSolarShading->ThetaMin = state.dataHeatBal->Blind(BlNum).MinSlatAngle * DataGlobalConstants::DegToRadians; state.dataSolarShading->ThetaMax = state.dataHeatBal->Blind(BlNum).MaxSlatAngle * DataGlobalConstants::DegToRadians; } - } - - switch (state.dataSurface->WindowShadingControl(IShadingCtrl).slatAngleControl) { - case SlatAngleControl::Fixed: { // 'FIXEDSLATANGLE' - state.dataSurface->SurfWinSlatAngThisTS(ISurf) = InputSlatAngle; - if ((state.dataSurface->SurfWinSlatAngThisTS(ISurf) <= state.dataSolarShading->ThetaSmall || - state.dataSurface->SurfWinSlatAngThisTS(ISurf) >= state.dataSolarShading->ThetaBig) && - (state.dataHeatBal->Blind(BlNum).SlatWidth > state.dataHeatBal->Blind(BlNum).SlatSeparation) && (BeamSolarOnWindow > 0.0)) - state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true; - } break; - case SlatAngleControl::Scheduled: { // 'SCHEDULEDSLATANGLE' - state.dataSurface->SurfWinSlatAngThisTS(ISurf) = - GetCurrentScheduleValue(state, state.dataSurface->WindowShadingControl(IShadingCtrl).SlatAngleSchedule); - state.dataSurface->SurfWinSlatAngThisTS(ISurf) = - max(state.dataHeatBal->Blind(BlNum).MinSlatAngle, - min(state.dataSurface->SurfWinSlatAngThisTS(ISurf), state.dataHeatBal->Blind(BlNum).MaxSlatAngle)) * - DataGlobalConstants::DegToRadians; - if ((state.dataSurface->SurfWinSlatAngThisTS(ISurf) <= state.dataSolarShading->ThetaSmall || - state.dataSurface->SurfWinSlatAngThisTS(ISurf) >= state.dataSolarShading->ThetaBig) && - (state.dataHeatBal->Blind(BlNum).SlatWidth > state.dataHeatBal->Blind(BlNum).SlatSeparation) && (BeamSolarOnWindow > 0.0)) - state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true; - } break; - case SlatAngleControl::BlockBeamSolar: { // 'BLOCKBEAMSOLAR' - if (BeamSolarOnWindow > 0.0) { - if (state.dataHeatBal->Blind(BlNum).SlatSeparation >= state.dataHeatBal->Blind(BlNum).SlatWidth) { - // TH 5/20/2010. CR 8064. - // The following line of code assumes slats are always vertical/closed to minimize solar penetration - // The slat angle can however change if the only goal is to block maximum amount of direct beam solar - // SurfaceWindow(ISurf)%SlatAngThisTS = 0.0 ! Allows beam penetration but minimizes it - - if (state.dataSolarShading->ThetaSmall >= state.dataSolarShading->ThetaMin && - state.dataSolarShading->ThetaSmall <= state.dataSolarShading->ThetaMax) { - state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaSmall; - } else if (state.dataSolarShading->ThetaBig >= state.dataSolarShading->ThetaMin && - state.dataSolarShading->ThetaBig <= state.dataSolarShading->ThetaMax) { - state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaBig; - } else if (state.dataSolarShading->ThetaSmall < state.dataSolarShading->ThetaMin && - state.dataSolarShading->ThetaBig < state.dataSolarShading->ThetaMin) { - state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaMin; - } else if (state.dataSolarShading->ThetaSmall > state.dataSolarShading->ThetaMax && - state.dataSolarShading->ThetaBig > state.dataSolarShading->ThetaMax) { - state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaMax; - } else { // ThetaBig > ThetaMax and ThetaSmall < ThetaMin (no-block condition) - state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaMin; - } - } else { // Usual case -- slat width greater than slat separation - if (state.dataSolarShading->ThetaSmall >= state.dataSolarShading->ThetaMin && - state.dataSolarShading->ThetaSmall <= state.dataSolarShading->ThetaMax) { - state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaSmall; - state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true; - } else if (state.dataSolarShading->ThetaBig >= state.dataSolarShading->ThetaMin && - state.dataSolarShading->ThetaBig <= state.dataSolarShading->ThetaMax) { - state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaBig; - state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true; - } else if (state.dataSolarShading->ThetaSmall < state.dataSolarShading->ThetaMin && - state.dataSolarShading->ThetaBig < state.dataSolarShading->ThetaMin) { - state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaMin; + // TH 5/20/2010, CR 8064: Slat Width <= Slat Separation + if (state.dataHeatBal->Blind(BlNum).SlatWidth <= state.dataHeatBal->Blind(BlNum).SlatSeparation && BeamSolarOnWindow > 0.0) { + if (state.dataSurface->WindowShadingControl(IShadingCtrl).slatAngleControl == SlatAngleControl::BlockBeamSolar) { + ProfAng = state.dataSurface->SurfWinProfileAng(ISurf); + if (std::abs(std::cos(ProfAng) * state.dataHeatBal->Blind(BlNum).SlatSeparation / + state.dataHeatBal->Blind(BlNum).SlatWidth) <= 1.0) { + // set to block 100% of beam solar, not necessarily to block maximum solar (beam + diffuse) + ThetaBase = std::acos(std::cos(ProfAng) * state.dataHeatBal->Blind(BlNum).SlatSeparation / + state.dataHeatBal->Blind(BlNum).SlatWidth); state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true; - } else if (state.dataSolarShading->ThetaSmall > state.dataSolarShading->ThetaMax && - state.dataSolarShading->ThetaBig > state.dataSolarShading->ThetaMax) { - state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaMax; - state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true; - } else { // ThetaBig > ThetaMax and ThetaSmall < ThetaMin (no-block condition) - state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaMin; + } else { + // cannot block 100% of beam solar, turn slats to be perpendicular to sun beam to block maximal beam solar + ThetaBase = 0.0; } + + // There are two solutions for the slat angle that just blocks beam radiation + ThetaBlock1 = ProfAng + ThetaBase; + ThetaBlock2 = ProfAng - ThetaBase + DataGlobalConstants::Pi; + + state.dataSolarShading->ThetaSmall = min(ThetaBlock1, ThetaBlock2); + state.dataSolarShading->ThetaBig = max(ThetaBlock1, ThetaBlock2); + state.dataSolarShading->ThetaMin = state.dataHeatBal->Blind(BlNum).MinSlatAngle * DataGlobalConstants::DegToRadians; + state.dataSolarShading->ThetaMax = state.dataHeatBal->Blind(BlNum).MaxSlatAngle * DataGlobalConstants::DegToRadians; } - } else { + } + + switch (state.dataSurface->WindowShadingControl(IShadingCtrl).slatAngleControl) { + case SlatAngleControl::Fixed: { // 'FIXEDSLATANGLE' state.dataSurface->SurfWinSlatAngThisTS(ISurf) = InputSlatAngle; + if ((state.dataSurface->SurfWinSlatAngThisTS(ISurf) <= state.dataSolarShading->ThetaSmall || + state.dataSurface->SurfWinSlatAngThisTS(ISurf) >= state.dataSolarShading->ThetaBig) && + (state.dataHeatBal->Blind(BlNum).SlatWidth > state.dataHeatBal->Blind(BlNum).SlatSeparation) && + (BeamSolarOnWindow > 0.0)) + state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true; + } break; + case SlatAngleControl::Scheduled: { // 'SCHEDULEDSLATANGLE' + state.dataSurface->SurfWinSlatAngThisTS(ISurf) = + GetCurrentScheduleValue(state, state.dataSurface->WindowShadingControl(IShadingCtrl).SlatAngleSchedule); + state.dataSurface->SurfWinSlatAngThisTS(ISurf) = + max(state.dataHeatBal->Blind(BlNum).MinSlatAngle, + min(state.dataSurface->SurfWinSlatAngThisTS(ISurf), state.dataHeatBal->Blind(BlNum).MaxSlatAngle)) * + DataGlobalConstants::DegToRadians; + if ((state.dataSurface->SurfWinSlatAngThisTS(ISurf) <= state.dataSolarShading->ThetaSmall || + state.dataSurface->SurfWinSlatAngThisTS(ISurf) >= state.dataSolarShading->ThetaBig) && + (state.dataHeatBal->Blind(BlNum).SlatWidth > state.dataHeatBal->Blind(BlNum).SlatSeparation) && + (BeamSolarOnWindow > 0.0)) + state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true; + } break; + case SlatAngleControl::BlockBeamSolar: { // 'BLOCKBEAMSOLAR' + if (BeamSolarOnWindow > 0.0) { + if (state.dataHeatBal->Blind(BlNum).SlatSeparation >= state.dataHeatBal->Blind(BlNum).SlatWidth) { + // TH 5/20/2010. CR 8064. + // The following line of code assumes slats are always vertical/closed to minimize solar penetration + // The slat angle can however change if the only goal is to block maximum amount of direct beam solar + // SurfaceWindow(ISurf)%SlatAngThisTS = 0.0 ! Allows beam penetration but minimizes it + + if (state.dataSolarShading->ThetaSmall >= state.dataSolarShading->ThetaMin && + state.dataSolarShading->ThetaSmall <= state.dataSolarShading->ThetaMax) { + state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaSmall; + } else if (state.dataSolarShading->ThetaBig >= state.dataSolarShading->ThetaMin && + state.dataSolarShading->ThetaBig <= state.dataSolarShading->ThetaMax) { + state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaBig; + } else if (state.dataSolarShading->ThetaSmall < state.dataSolarShading->ThetaMin && + state.dataSolarShading->ThetaBig < state.dataSolarShading->ThetaMin) { + state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaMin; + } else if (state.dataSolarShading->ThetaSmall > state.dataSolarShading->ThetaMax && + state.dataSolarShading->ThetaBig > state.dataSolarShading->ThetaMax) { + state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaMax; + } else { // ThetaBig > ThetaMax and ThetaSmall < ThetaMin (no-block condition) + state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaMin; + } + + } else { // Usual case -- slat width greater than slat separation + if (state.dataSolarShading->ThetaSmall >= state.dataSolarShading->ThetaMin && + state.dataSolarShading->ThetaSmall <= state.dataSolarShading->ThetaMax) { + state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaSmall; + state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true; + } else if (state.dataSolarShading->ThetaBig >= state.dataSolarShading->ThetaMin && + state.dataSolarShading->ThetaBig <= state.dataSolarShading->ThetaMax) { + state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaBig; + state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true; + } else if (state.dataSolarShading->ThetaSmall < state.dataSolarShading->ThetaMin && + state.dataSolarShading->ThetaBig < state.dataSolarShading->ThetaMin) { + state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaMin; + state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true; + } else if (state.dataSolarShading->ThetaSmall > state.dataSolarShading->ThetaMax && + state.dataSolarShading->ThetaBig > state.dataSolarShading->ThetaMax) { + state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaMax; + state.dataSurface->SurfWinSlatsBlockBeam(ISurf) = true; + } else { // ThetaBig > ThetaMax and ThetaSmall < ThetaMin (no-block condition) + state.dataSurface->SurfWinSlatAngThisTS(ISurf) = state.dataSolarShading->ThetaMin; + } + } + } else { + state.dataSurface->SurfWinSlatAngThisTS(ISurf) = InputSlatAngle; + } + } break; + default: + break; } - } break; - default: - break; - } - state.dataSurface->SurfWinSlatAngThisTSDeg(ISurf) = - state.dataSurface->SurfWinSlatAngThisTS(ISurf) / DataGlobalConstants::DegToRadians; - if (state.dataSurface->SurfWinSlatAngThisTSDegEMSon(ISurf)) { - state.dataSurface->SurfWinSlatAngThisTSDeg(ISurf) = state.dataSurface->SurfWinSlatAngThisTSDegEMSValue(ISurf); - state.dataSurface->SurfWinSlatAngThisTS(ISurf) = - DataGlobalConstants::DegToRadians * state.dataSurface->SurfWinSlatAngThisTSDeg(ISurf); - } - // Air flow permeability for calculation of convective air flow between blind and glass - SlatAng = state.dataSurface->SurfWinSlatAngThisTS(ISurf); - PermeabilityA = - std::sin(SlatAng) - state.dataHeatBal->Blind(BlNum).SlatThickness / state.dataHeatBal->Blind(BlNum).SlatSeparation; - PermeabilityB = 1.0 - (std::abs(state.dataHeatBal->Blind(BlNum).SlatWidth * std::cos(SlatAng)) + - state.dataHeatBal->Blind(BlNum).SlatThickness * std::sin(SlatAng)) / - state.dataHeatBal->Blind(BlNum).SlatSeparation; - state.dataSurface->SurfWinBlindAirFlowPermeability(ISurf) = min(1.0, max(0.0, PermeabilityA, PermeabilityB)); - state.dataSurface->SurfWinBlindBmBmTrans(ISurf) = General::BlindBeamBeamTrans(ProfAng, - SlatAng, - state.dataHeatBal->Blind(BlNum).SlatWidth, - state.dataHeatBal->Blind(BlNum).SlatSeparation, - state.dataHeatBal->Blind(BlNum).SlatThickness); - // Calculate blind interpolation factors and indices. - if (state.dataSurface->SurfWinMovableSlats(ISurf)) { - if (SlatAng > DataGlobalConstants::Pi || SlatAng < 0.0) { - SlatAng = min(max(SlatAng, 0.0), DataGlobalConstants::Pi); + state.dataSurface->SurfWinSlatAngThisTSDeg(ISurf) = + state.dataSurface->SurfWinSlatAngThisTS(ISurf) / DataGlobalConstants::DegToRadians; + if (state.dataSurface->SurfWinSlatAngThisTSDegEMSon(ISurf)) { + state.dataSurface->SurfWinSlatAngThisTSDeg(ISurf) = state.dataSurface->SurfWinSlatAngThisTSDegEMSValue(ISurf); + state.dataSurface->SurfWinSlatAngThisTS(ISurf) = + DataGlobalConstants::DegToRadians * state.dataSurface->SurfWinSlatAngThisTSDeg(ISurf); + } + // Air flow permeability for calculation of convective air flow between blind and glass + SlatAng = state.dataSurface->SurfWinSlatAngThisTS(ISurf); + PermeabilityA = + std::sin(SlatAng) - state.dataHeatBal->Blind(BlNum).SlatThickness / state.dataHeatBal->Blind(BlNum).SlatSeparation; + PermeabilityB = 1.0 - (std::abs(state.dataHeatBal->Blind(BlNum).SlatWidth * std::cos(SlatAng)) + + state.dataHeatBal->Blind(BlNum).SlatThickness * std::sin(SlatAng)) / + state.dataHeatBal->Blind(BlNum).SlatSeparation; + state.dataSurface->SurfWinBlindAirFlowPermeability(ISurf) = min(1.0, max(0.0, PermeabilityA, PermeabilityB)); + state.dataSurface->SurfWinBlindBmBmTrans(ISurf) = General::BlindBeamBeamTrans(ProfAng, + SlatAng, + state.dataHeatBal->Blind(BlNum).SlatWidth, + state.dataHeatBal->Blind(BlNum).SlatSeparation, + state.dataHeatBal->Blind(BlNum).SlatThickness); + // Calculate blind interpolation factors and indices. + if (state.dataSurface->SurfWinMovableSlats(ISurf)) { + if (SlatAng > DataGlobalConstants::Pi || SlatAng < 0.0) { + SlatAng = min(max(SlatAng, 0.0), DataGlobalConstants::Pi); + } + Real64 SlatsAngIndex = 1 + int(SlatAng * DeltaAng_inv); + state.dataSurface->SurfWinSlatsAngIndex(ISurf) = SlatsAngIndex; + state.dataSurface->SurfWinSlatsAngInterpFac(ISurf) = (SlatAng - DeltaAng * (SlatsAngIndex - 1)) * DeltaAng_inv; } - Real64 SlatsAngIndex = 1 + int(SlatAng * DeltaAng_inv); - state.dataSurface->SurfWinSlatsAngIndex(ISurf) = SlatsAngIndex; - state.dataSurface->SurfWinSlatsAngInterpFac(ISurf) = (SlatAng - DeltaAng * (SlatsAngIndex - 1)) * DeltaAng_inv; } - } - } // End of check if interior or exterior or between glass blind in place + } // End of check if interior or exterior or between glass blind in place - // CALL CalcScreenTransmittance to intialized all screens prior to HB calc's - if (state.dataSurface->SurfWinShadingFlag(ISurf) == WinShadingType::ExtScreen && state.dataEnvrn->SunIsUp) { - CalcScreenTransmittance(state, ISurf); - } + // CALL CalcScreenTransmittance to intialized all screens prior to HB calc's + if (state.dataSurface->SurfWinShadingFlag(ISurf) == WinShadingType::ExtScreen && state.dataEnvrn->SunIsUp) { + CalcScreenTransmittance(state, ISurf); + } - // EMS Actuator Point: override setting if ems flag on - if (state.dataSurface->SurfWinShadingFlagEMSOn(ISurf)) { - WinShadingType SurfWinShadingFlagEMS = findValueInEnumeration(state.dataSurface->SurfWinShadingFlagEMSValue(ISurf)); - if (SurfWinShadingFlagEMS != WinShadingType::Invalid) { - state.dataSurface->SurfWinShadingFlag(ISurf) = SurfWinShadingFlagEMS; - } else { - ShowWarningError(state, "Invalid EMS value of Window Shading Control Type for Surface " + state.dataSurface->Surface(ISurf).Name); + // EMS Actuator Point: override setting if ems flag on + if (state.dataSurface->SurfWinShadingFlagEMSOn(ISurf)) { + WinShadingType SurfWinShadingFlagEMS = findValueInEnumeration(state.dataSurface->SurfWinShadingFlagEMSValue(ISurf)); + if (SurfWinShadingFlagEMS != WinShadingType::Invalid) { + state.dataSurface->SurfWinShadingFlag(ISurf) = SurfWinShadingFlagEMS; + } else { + ShowWarningError(state, + "Invalid EMS value of Window Shading Control Type for Surface " + state.dataSurface->Surface(ISurf).Name); + } } - } - } // End of surface loop + } // End of surface loop + } } } @@ -10130,12 +10160,14 @@ void CheckGlazingShadingStatusChange(EnergyPlusData &state) state.dataHeatBal->EnclRadAlwaysReCalc = true; } else { for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { - for (int SurfNum = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst; SurfNum <= state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast; - ++SurfNum) { - if (state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).TCFlag == 1 || - state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).WindowTypeEQL) { - state.dataHeatBal->EnclRadAlwaysReCalc = true; - break; + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { + if (state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).TCFlag == 1 || + state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).WindowTypeEQL) { + state.dataHeatBal->EnclRadAlwaysReCalc = true; + break; + } } } } @@ -10201,12 +10233,13 @@ DataSurfaces::WinShadingType findValueInEnumeration(Real64 controlValue) // 8: if between-glass shade is on // 9: if between-glass blind is on // 10: window has interior shade that is off but may be triggered on later to control daylight glare - // 20: window has switchable glazing that is unswitched but may be switched later to control daylight glare or daylight illuminance - // 30: window has exterior shade that is off but may be triggered on later to control daylight glare or daylight illuminance - // 60: window has interior blind that is off but may be triggered on later to control daylight glare or daylight illuminance - // 70: window has exterior blind that is off but may be triggered on later to control daylight glare or daylight illuminance - // 80: window has between-glass shade that is off but may be triggered on later to control daylight glare or daylight illuminance - // 90: window has between-glass blind that is off but may be triggered on later to control daylight glare or daylight illuminance + // 20: window has switchable glazing that is unswitched but may be switched later to control daylight glare or + // daylight illuminance 30: window has exterior shade that is off but may be triggered on later to control + // daylight glare or daylight illuminance 60: window has interior blind that is off but may be triggered on later + // to control daylight glare or daylight illuminance 70: window has exterior blind that is off but may be + // triggered on later to control daylight glare or daylight illuminance 80: window has between-glass shade that is + // off but may be triggered on later to control daylight glare or daylight illuminance 90: window has + // between-glass blind that is off but may be triggered on later to control daylight glare or daylight illuminance if (controlValue == -1.0) return WinShadingType::NoShade; if (controlValue == 0.0) return WinShadingType::ShadeOff; if (controlValue == 1.0) return WinShadingType::IntShade; @@ -10229,9 +10262,10 @@ DataSurfaces::WinShadingType findValueInEnumeration(Real64 controlValue) int selectActiveWindowShadingControlIndex(EnergyPlusData &state, int curSurface) { - // For a given surface, determine based on the schedules which index to the window shading control list vector should be active - int selected = 0; // presume it is the first shading control - even if it is not active it needs to be some shading control which is then turned - // off in the WindowShadingManager + // For a given surface, determine based on the schedules which index to the window shading control list vector + // should be active + int selected = 0; // presume it is the first shading control - even if it is not active it needs to be some + // shading control which is then turned off in the WindowShadingManager if (state.dataSurface->Surface(curSurface).windowShadingControlList.size() > 1) { for (std::size_t listIndex = 0; listIndex < state.dataSurface->Surface(curSurface).windowShadingControlList.size(); ++listIndex) { int wsc = state.dataSurface->Surface(curSurface).windowShadingControlList[listIndex]; @@ -10265,37 +10299,40 @@ void WindowGapAirflowControl(EnergyPlusData &state) using ScheduleManager::GetCurrentScheduleValue; for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceFirst; - int const lastSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceLast; - for (int ISurf = firstSurfWin; ISurf <= lastSurfWin; ++ISurf) { - - state.dataSurface->SurfWinAirflowThisTS(ISurf) = 0.0; - if (state.dataSurface->SurfWinMaxAirflow(ISurf) == 0.0) continue; - if (state.dataSurface->Surface(ISurf).ExtBoundCond != ExternalEnvironment) continue; - switch (state.dataSurface->SurfWinAirflowControlType(ISurf)) { - case WindowAirFlowControlType::MaxFlow: { - state.dataSurface->SurfWinAirflowThisTS(ISurf) = state.dataSurface->SurfWinMaxAirflow(ISurf); - } break; - case WindowAirFlowControlType::AlwaysOff: { + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurfWin = thisSpace.WindowSurfaceFirst; + int const lastSurfWin = thisSpace.WindowSurfaceLast; + for (int ISurf = firstSurfWin; ISurf <= lastSurfWin; ++ISurf) { + state.dataSurface->SurfWinAirflowThisTS(ISurf) = 0.0; - } break; - case WindowAirFlowControlType::Schedule: { - if (state.dataSurface->SurfWinAirflowHasSchedule(ISurf)) { - int SchedulePtr = state.dataSurface->SurfWinAirflowSchedulePtr(ISurf); // Schedule pointer - Real64 ScheduleMult = GetCurrentScheduleValue(state, SchedulePtr); // Multiplier value from schedule - if (ScheduleMult < 0.0 || ScheduleMult > 1.0) { - ShowFatalError( - state, "Airflow schedule has a value outside the range 0.0 to 1.0 for window=" + state.dataSurface->Surface(ISurf).Name); + if (state.dataSurface->SurfWinMaxAirflow(ISurf) == 0.0) continue; + if (state.dataSurface->Surface(ISurf).ExtBoundCond != ExternalEnvironment) continue; + switch (state.dataSurface->SurfWinAirflowControlType(ISurf)) { + case WindowAirFlowControlType::MaxFlow: { + state.dataSurface->SurfWinAirflowThisTS(ISurf) = state.dataSurface->SurfWinMaxAirflow(ISurf); + } break; + case WindowAirFlowControlType::AlwaysOff: { + state.dataSurface->SurfWinAirflowThisTS(ISurf) = 0.0; + } break; + case WindowAirFlowControlType::Schedule: { + if (state.dataSurface->SurfWinAirflowHasSchedule(ISurf)) { + int SchedulePtr = state.dataSurface->SurfWinAirflowSchedulePtr(ISurf); // Schedule pointer + Real64 ScheduleMult = GetCurrentScheduleValue(state, SchedulePtr); // Multiplier value from schedule + if (ScheduleMult < 0.0 || ScheduleMult > 1.0) { + ShowFatalError(state, + "Airflow schedule has a value outside the range 0.0 to 1.0 for window=" + + state.dataSurface->Surface(ISurf).Name); + } + state.dataSurface->SurfWinAirflowThisTS(ISurf) = ScheduleMult * state.dataSurface->SurfWinMaxAirflow(ISurf); } - state.dataSurface->SurfWinAirflowThisTS(ISurf) = ScheduleMult * state.dataSurface->SurfWinMaxAirflow(ISurf); + } break; + default: + break; } - } break; - default: - break; - } - } - - } // End of surface loop + } // End of surface loop + } // End of space loop + } // End of zone loop } void SkyDifSolarShading(EnergyPlusData &state) @@ -10356,9 +10393,11 @@ void SkyDifSolarShading(EnergyPlusData &state) // ! sky on surface, with shading // REAL(r64), ALLOCATABLE, DIMENSION(:) :: WoShdgIsoSky ! Diffuse solar from isotropic // ! sky on surface, without shading - // REAL(r64), ALLOCATABLE, DIMENSION(:) :: WithShdgHoriz ! Diffuse solar irradiance from horizon portion of + // REAL(r64), ALLOCATABLE, DIMENSION(:) :: WithShdgHoriz ! Diffuse solar irradiance from horizon portion + // of // ! sky on surface, with shading - // REAL(r64), ALLOCATABLE, DIMENSION(:) :: WoShdgHoriz ! Diffuse solar irradiance from horizon portion of + // REAL(r64), ALLOCATABLE, DIMENSION(:) :: WoShdgHoriz ! Diffuse solar irradiance from horizon portion + // of // ! sky on surface, without shading // INTEGER iHour,iTS @@ -10573,53 +10612,57 @@ void CalcWindowProfileAngles(EnergyPlusData &state) Real64 const sin_ElevSun = std::sin(ElevSun); for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceFirst; - int const lastSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceLast; - for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurfWin = thisSpace.WindowSurfaceFirst; + int const lastSurfWin = thisSpace.WindowSurfaceLast; + for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { - if (state.dataSurface->Surface(SurfNum).ExtBoundCond != ExternalEnvironment && - state.dataSurface->Surface(SurfNum).ExtBoundCond != OtherSideCondModeledExt) - continue; + if (state.dataSurface->Surface(SurfNum).ExtBoundCond != ExternalEnvironment && + state.dataSurface->Surface(SurfNum).ExtBoundCond != OtherSideCondModeledExt) + continue; - state.dataSurface->SurfWinProfileAngHor(SurfNum) = 0.0; - state.dataSurface->SurfWinProfileAngVert(SurfNum) = 0.0; - if (state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) <= 0.0) continue; - - ElevWin = DataGlobalConstants::PiOvr2 - state.dataSurface->Surface(SurfNum).Tilt * DataGlobalConstants::DegToRadians; - AzimWin = state.dataSurface->Surface(SurfNum).Azimuth * DataGlobalConstants::DegToRadians; - - ProfileAngHor = std::atan(sin_ElevSun / std::abs(cos_ElevSun * std::cos(AzimWin - AzimSun))) - ElevWin; - - // CR9280 - were having negative profile angles on west sides. commenting out previous code (original code) for - // vertical windows - // IF(ABS(ElevWin) < 0.1d0) THEN ! Near-vertical window - // ProfileAngVert = ABS(AzimWin-AzimSun) - // ELSE - WinNorm = state.dataSurface->Surface(SurfNum).OutNormVec; - ThWin = AzimWin - DataGlobalConstants::PiOvr2; - Real64 const sin_Elevwin(std::sin(ElevWin)); - WinNormCrossBase.x = -(sin_Elevwin * std::cos(ThWin)); - WinNormCrossBase.y = sin_Elevwin * std::sin(ThWin); - WinNormCrossBase.z = std::cos(ElevWin); - SunPrime = SolCosVec - WinNormCrossBase * dot(SolCosVec, WinNormCrossBase); - dot1 = dot(WinNorm, SunPrime); - dot2 = SunPrime.magnitude(); - dot3 = dot1 / dot2; - if (dot3 > 1.0) { - dot3 = 1.0; - } else if (dot3 < -1.0) { - dot3 = -1.0; - } - // ProfileAngVert = ABS(ACOS(DOT_PRODUCT(WinNorm,SunPrime)/SQRT(DOT_PRODUCT(SunPrime,SunPrime)))) - ProfileAngVert = std::abs(std::acos(dot3)); - // END IF - // Constrain to 0 to pi - if (ProfileAngVert > DataGlobalConstants::Pi) ProfileAngVert = DataGlobalConstants::TwoPi - ProfileAngVert; - - state.dataSurface->SurfWinProfileAngHor(SurfNum) = ProfileAngHor / DataGlobalConstants::DegToRadians; - state.dataSurface->SurfWinProfileAngVert(SurfNum) = ProfileAngVert / DataGlobalConstants::DegToRadians; - state.dataSurface->SurfWinTanProfileAngHor(SurfNum) = std::abs(std::tan(ProfileAngHor)); - state.dataSurface->SurfWinTanProfileAngVert(SurfNum) = std::abs(std::tan(ProfileAngVert)); + state.dataSurface->SurfWinProfileAngHor(SurfNum) = 0.0; + state.dataSurface->SurfWinProfileAngVert(SurfNum) = 0.0; + if (state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) <= 0.0) continue; + + ElevWin = DataGlobalConstants::PiOvr2 - state.dataSurface->Surface(SurfNum).Tilt * DataGlobalConstants::DegToRadians; + AzimWin = state.dataSurface->Surface(SurfNum).Azimuth * DataGlobalConstants::DegToRadians; + + ProfileAngHor = std::atan(sin_ElevSun / std::abs(cos_ElevSun * std::cos(AzimWin - AzimSun))) - ElevWin; + + // CR9280 - were having negative profile angles on west sides. commenting out previous code + // (original code) for vertical windows + // IF(ABS(ElevWin) < 0.1d0) THEN ! Near-vertical window + // ProfileAngVert = ABS(AzimWin-AzimSun) + // ELSE + WinNorm = state.dataSurface->Surface(SurfNum).OutNormVec; + ThWin = AzimWin - DataGlobalConstants::PiOvr2; + Real64 const sin_Elevwin(std::sin(ElevWin)); + WinNormCrossBase.x = -(sin_Elevwin * std::cos(ThWin)); + WinNormCrossBase.y = sin_Elevwin * std::sin(ThWin); + WinNormCrossBase.z = std::cos(ElevWin); + SunPrime = SolCosVec - WinNormCrossBase * dot(SolCosVec, WinNormCrossBase); + dot1 = dot(WinNorm, SunPrime); + dot2 = SunPrime.magnitude(); + dot3 = dot1 / dot2; + if (dot3 > 1.0) { + dot3 = 1.0; + } else if (dot3 < -1.0) { + dot3 = -1.0; + } + // ProfileAngVert = + // ABS(ACOS(DOT_PRODUCT(WinNorm,SunPrime)/SQRT(DOT_PRODUCT(SunPrime,SunPrime)))) + ProfileAngVert = std::abs(std::acos(dot3)); + // END IF + // Constrain to 0 to pi + if (ProfileAngVert > DataGlobalConstants::Pi) ProfileAngVert = DataGlobalConstants::TwoPi - ProfileAngVert; + + state.dataSurface->SurfWinProfileAngHor(SurfNum) = ProfileAngHor / DataGlobalConstants::DegToRadians; + state.dataSurface->SurfWinProfileAngVert(SurfNum) = ProfileAngVert / DataGlobalConstants::DegToRadians; + state.dataSurface->SurfWinTanProfileAngHor(SurfNum) = std::abs(std::tan(ProfileAngHor)); + state.dataSurface->SurfWinTanProfileAngVert(SurfNum) = std::abs(std::tan(ProfileAngVert)); + } } } } @@ -10960,358 +11003,366 @@ void CalcBeamSolarOnWinRevealSurface(EnergyPlusData &state) Real64 tmp_SunlitFracWithoutReveal; // Temporary variable for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceFirst; - int const lastSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceLast; - for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { - // Added TH for initialization. CR 7596 inside reveal causing high cooling loads - // for outside reveals - state.dataSurface->SurfWinBmSolAbsdOutsReveal(SurfNum) = 0.0; - state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfNum) = 0.0; - state.dataSurface->SurfWinBmSolRefldOutsRevealRepEnergy(SurfNum) = 0.0; - state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) = 0.0; - state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) = 0.0; - // for inside reveals - state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) = 0.0; - state.dataSurface->SurfWinBmSolAbsdInsRevealReport(SurfNum) = 0.0; - state.dataSurface->SurfWinBmSolRefldInsReveal(SurfNum) = 0.0; - state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfNum) = 0.0; - state.dataSurface->SurfWinBmSolRefldInsRevealRepEnergy(SurfNum) = 0.0; - state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum) = 0.0; - state.dataSurface->SurfWinInsRevealDiffOntoGlazingReport(SurfNum) = 0.0; - state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) = 0.0; - state.dataSurface->SurfWinInsRevealDiffOntoFrameReport(SurfNum) = 0.0; - state.dataSurface->SurfWinInsRevealDiffIntoZone(SurfNum) = 0.0; - state.dataSurface->SurfWinInsRevealDiffIntoZoneReport(SurfNum) = 0.0; - - if ((state.dataSurface->Surface(SurfNum).ExtBoundCond != ExternalEnvironment && - state.dataSurface->Surface(SurfNum).ExtBoundCond != OtherSideCondModeledExt)) - continue; - if (state.dataSurface->Surface(SurfNum).Reveal == 0.0 && state.dataSurface->SurfWinInsideReveal(SurfNum) == 0.0 && - state.dataSurface->SurfWinInsideSillDepth(SurfNum) == 0.0) - continue; - if (state.dataSurface->Surface(SurfNum).Sides != 4) continue; - if (state.dataSurface->SurfWinInsideSillDepth(SurfNum) < state.dataSurface->SurfWinInsideReveal(SurfNum)) continue; - - ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum); - if (BITF_TEST_ANY(BITF(ShadeFlag), BITF(WinShadingType::ExtShade) | BITF(WinShadingType::ExtBlind))) continue; - - if (state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) <= 0.0) continue; - - tmp_SunlitFracWithoutReveal = - state.dataHeatBal->SurfSunlitFracWithoutReveal(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum); - - // Calculate cosine of angle of incidence of beam solar on reveal surfaces, - // assumed to be perpendicular to window plane - - CosBetaBottom = -state.dataEnvrn->SOLCOS(1) * state.dataSurface->Surface(SurfNum).SinAzim * state.dataSurface->Surface(SurfNum).CosTilt - - state.dataEnvrn->SOLCOS(2) * state.dataSurface->Surface(SurfNum).CosAzim * state.dataSurface->Surface(SurfNum).CosTilt + - state.dataEnvrn->SOLCOS(3) * state.dataSurface->Surface(SurfNum).SinTilt; - - CosBetaLeft = -state.dataEnvrn->SOLCOS(1) * state.dataSurface->Surface(SurfNum).CosAzim - - state.dataEnvrn->SOLCOS(2) * state.dataSurface->Surface(SurfNum).SinAzim; - - // Note: CosBetaTop = -CosBetaBottom, CosBetaRight = -CosBetaLeft - - OutsReveal = state.dataSurface->Surface(SurfNum).Reveal; - InsReveal = state.dataSurface->SurfWinInsideReveal(SurfNum); - InsideRevealSolAbs = 0.0; - GlazingThickness = state.dataSurface->SurfWinTotGlazingThickness(SurfNum); - H = state.dataSurface->Surface(SurfNum).Height; - W = state.dataSurface->Surface(SurfNum).Width; - d1 = OutsReveal + 0.5 * GlazingThickness; - ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); - ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum); - - SolTransGlass = POLYF(state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum), - state.dataConstruction->Construct(ConstrNum).TransSolBeamCoef); - TanProfileAngVert = state.dataSurface->SurfWinTanProfileAngVert(SurfNum); - TanProfileAngHor = state.dataSurface->SurfWinTanProfileAngHor(SurfNum); - FrameDivNum = state.dataSurface->Surface(SurfNum).FrameDivider; - FrameWidth = 0.0; - if (FrameDivNum != 0) { - FrameWidth = state.dataSurface->FrameDivider(FrameDivNum).FrameWidth; - if (FrameWidth > 0.0) { - P1 = state.dataSurface->FrameDivider(FrameDivNum).FrameProjectionOut + 0.5 * GlazingThickness; - P2 = state.dataSurface->FrameDivider(FrameDivNum).FrameProjectionIn + 0.5 * GlazingThickness; - if (OutsReveal + 0.5 * GlazingThickness <= P1) d1 = P1 + 0.001; - } - } - // Loop over vertical and horizontal reveal surfaces - for (HorVertReveal = 1; HorVertReveal <= 2; ++HorVertReveal) { - - FracToGlassOuts = 0.5; - FracToGlassIns = 0.5; - BmSolRefldOutsReveal = 0.0; - BmSolRefldInsReveal = 0.0; - A1ill = 0.0; - A2ill = 0.0; - - // Added TH. 5/27/2009 - A1sh = 0.0; - A2sh = 0.0; - - if (HorVertReveal == 1) { // Vertical reveal - TanAlpha = TanProfileAngHor; - TanGamma = TanProfileAngVert; - CosBeta = std::abs(CosBetaLeft); - L = state.dataSurface->Surface(SurfNum).Height; - d2 = InsReveal + 0.5 * GlazingThickness; - d2prime = d1 + d2 - W / TanGamma; - InsideRevealSolAbs = state.dataSurface->SurfWinInsideRevealSolAbs(SurfNum); - } else { // Horizontal reveal - InsSillDepth = state.dataSurface->SurfWinInsideSillDepth(SurfNum); - TanAlpha = TanProfileAngVert; - TanGamma = TanProfileAngHor; - CosBeta = std::abs(CosBetaBottom); - L = state.dataSurface->Surface(SurfNum).Width; - if (CosBetaBottom > 0.0) { // Bottom reveal surfaces may be illuminated - d2 = InsSillDepth + 0.5 * GlazingThickness; - InsideRevealSolAbs = state.dataSurface->SurfWinInsideSillSolAbs(SurfNum); - } else { // Top reveal surfaces may be illuminated - d2 = InsReveal + 0.5 * GlazingThickness; - InsideRevealSolAbs = state.dataSurface->SurfWinInsideRevealSolAbs(SurfNum); + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurfWin = thisSpace.WindowSurfaceFirst; + int const lastSurfWin = thisSpace.WindowSurfaceLast; + for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { + // Added TH for initialization. CR 7596 inside reveal causing high cooling loads + // for outside reveals + state.dataSurface->SurfWinBmSolAbsdOutsReveal(SurfNum) = 0.0; + state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfNum) = 0.0; + state.dataSurface->SurfWinBmSolRefldOutsRevealRepEnergy(SurfNum) = 0.0; + state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) = 0.0; + state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) = 0.0; + // for inside reveals + state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) = 0.0; + state.dataSurface->SurfWinBmSolAbsdInsRevealReport(SurfNum) = 0.0; + state.dataSurface->SurfWinBmSolRefldInsReveal(SurfNum) = 0.0; + state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfNum) = 0.0; + state.dataSurface->SurfWinBmSolRefldInsRevealRepEnergy(SurfNum) = 0.0; + state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum) = 0.0; + state.dataSurface->SurfWinInsRevealDiffOntoGlazingReport(SurfNum) = 0.0; + state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) = 0.0; + state.dataSurface->SurfWinInsRevealDiffOntoFrameReport(SurfNum) = 0.0; + state.dataSurface->SurfWinInsRevealDiffIntoZone(SurfNum) = 0.0; + state.dataSurface->SurfWinInsRevealDiffIntoZoneReport(SurfNum) = 0.0; + + if ((state.dataSurface->Surface(SurfNum).ExtBoundCond != ExternalEnvironment && + state.dataSurface->Surface(SurfNum).ExtBoundCond != OtherSideCondModeledExt)) + continue; + if (state.dataSurface->Surface(SurfNum).Reveal == 0.0 && state.dataSurface->SurfWinInsideReveal(SurfNum) == 0.0 && + state.dataSurface->SurfWinInsideSillDepth(SurfNum) == 0.0) + continue; + if (state.dataSurface->Surface(SurfNum).Sides != 4) continue; + if (state.dataSurface->SurfWinInsideSillDepth(SurfNum) < state.dataSurface->SurfWinInsideReveal(SurfNum)) continue; + + ShadeFlag = state.dataSurface->SurfWinShadingFlag(SurfNum); + if (BITF_TEST_ANY(BITF(ShadeFlag), BITF(WinShadingType::ExtShade) | BITF(WinShadingType::ExtBlind))) continue; + + if (state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum) <= 0.0) continue; + + tmp_SunlitFracWithoutReveal = + state.dataHeatBal->SurfSunlitFracWithoutReveal(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum); + + // Calculate cosine of angle of incidence of beam solar on reveal surfaces, + // assumed to be perpendicular to window plane + + CosBetaBottom = + -state.dataEnvrn->SOLCOS(1) * state.dataSurface->Surface(SurfNum).SinAzim * state.dataSurface->Surface(SurfNum).CosTilt - + state.dataEnvrn->SOLCOS(2) * state.dataSurface->Surface(SurfNum).CosAzim * state.dataSurface->Surface(SurfNum).CosTilt + + state.dataEnvrn->SOLCOS(3) * state.dataSurface->Surface(SurfNum).SinTilt; + + CosBetaLeft = -state.dataEnvrn->SOLCOS(1) * state.dataSurface->Surface(SurfNum).CosAzim - + state.dataEnvrn->SOLCOS(2) * state.dataSurface->Surface(SurfNum).SinAzim; + + // Note: CosBetaTop = -CosBetaBottom, CosBetaRight = -CosBetaLeft + + OutsReveal = state.dataSurface->Surface(SurfNum).Reveal; + InsReveal = state.dataSurface->SurfWinInsideReveal(SurfNum); + InsideRevealSolAbs = 0.0; + GlazingThickness = state.dataSurface->SurfWinTotGlazingThickness(SurfNum); + H = state.dataSurface->Surface(SurfNum).Height; + W = state.dataSurface->Surface(SurfNum).Width; + d1 = OutsReveal + 0.5 * GlazingThickness; + ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); + ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(SurfNum); + + SolTransGlass = POLYF(state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum), + state.dataConstruction->Construct(ConstrNum).TransSolBeamCoef); + TanProfileAngVert = state.dataSurface->SurfWinTanProfileAngVert(SurfNum); + TanProfileAngHor = state.dataSurface->SurfWinTanProfileAngHor(SurfNum); + FrameDivNum = state.dataSurface->Surface(SurfNum).FrameDivider; + FrameWidth = 0.0; + if (FrameDivNum != 0) { + FrameWidth = state.dataSurface->FrameDivider(FrameDivNum).FrameWidth; + if (FrameWidth > 0.0) { + P1 = state.dataSurface->FrameDivider(FrameDivNum).FrameProjectionOut + 0.5 * GlazingThickness; + P2 = state.dataSurface->FrameDivider(FrameDivNum).FrameProjectionIn + 0.5 * GlazingThickness; + if (OutsReveal + 0.5 * GlazingThickness <= P1) d1 = P1 + 0.001; } - d2prime = d1 + d2 - H / TanGamma; } - if (d2prime < 0.0) d2prime = 0.0; // No shadow from opposing reveal - d12 = d1 + d2 - d2prime; + // Loop over vertical and horizontal reveal surfaces + for (HorVertReveal = 1; HorVertReveal <= 2; ++HorVertReveal) { - if (FrameWidth <= 0.001) { - // Window without frame + FracToGlassOuts = 0.5; + FracToGlassIns = 0.5; + BmSolRefldOutsReveal = 0.0; + BmSolRefldInsReveal = 0.0; + A1ill = 0.0; + A2ill = 0.0; - // Find inside and outside shadowed area of vertical or horizontal reveal surfaces - // that can be illuminated by beam solar; shadowing is by other reveal surfaces. + // Added TH. 5/27/2009 + A1sh = 0.0; + A2sh = 0.0; - if (d2prime <= d2) { - if (d12 * TanAlpha <= L) { - A1sh = 0.5 * TanAlpha * pow_2(d1); - A2sh = d2prime * L + 0.5 * TanAlpha * pow_2(d12) - A1sh; - } else { // d12*TanAlpha > L - if (d1 * TanAlpha <= L) { - A1sh = 0.5 * TanAlpha * pow_2(d1); - A2sh = d2 * L - 0.5 * TanAlpha * pow_2(L / TanAlpha - d1); - } else { // d1*TanAlpha > L - A1sh = d1 * L - (0.5 / TanAlpha) * pow_2(L); - A2sh = d2 * L; - } + if (HorVertReveal == 1) { // Vertical reveal + TanAlpha = TanProfileAngHor; + TanGamma = TanProfileAngVert; + CosBeta = std::abs(CosBetaLeft); + L = state.dataSurface->Surface(SurfNum).Height; + d2 = InsReveal + 0.5 * GlazingThickness; + d2prime = d1 + d2 - W / TanGamma; + InsideRevealSolAbs = state.dataSurface->SurfWinInsideRevealSolAbs(SurfNum); + } else { // Horizontal reveal + InsSillDepth = state.dataSurface->SurfWinInsideSillDepth(SurfNum); + TanAlpha = TanProfileAngVert; + TanGamma = TanProfileAngHor; + CosBeta = std::abs(CosBetaBottom); + L = state.dataSurface->Surface(SurfNum).Width; + if (CosBetaBottom > 0.0) { // Bottom reveal surfaces may be illuminated + d2 = InsSillDepth + 0.5 * GlazingThickness; + InsideRevealSolAbs = state.dataSurface->SurfWinInsideSillSolAbs(SurfNum); + } else { // Top reveal surfaces may be illuminated + d2 = InsReveal + 0.5 * GlazingThickness; + InsideRevealSolAbs = state.dataSurface->SurfWinInsideRevealSolAbs(SurfNum); } - } else { // d2prime > d2 - A2sh = d2 * L; - if (d2prime < d1 + d2) { + d2prime = d1 + d2 - H / TanGamma; + } + if (d2prime < 0.0) d2prime = 0.0; // No shadow from opposing reveal + d12 = d1 + d2 - d2prime; + + if (FrameWidth <= 0.001) { + // Window without frame + + // Find inside and outside shadowed area of vertical or horizontal reveal surfaces + // that can be illuminated by beam solar; shadowing is by other reveal surfaces. + + if (d2prime <= d2) { if (d12 * TanAlpha <= L) { - A1sh = L * (d2prime - d2) + 0.5 * TanAlpha * pow_2(d12); + A1sh = 0.5 * TanAlpha * pow_2(d1); + A2sh = d2prime * L + 0.5 * TanAlpha * pow_2(d12) - A1sh; } else { // d12*TanAlpha > L - A1sh = d1 * L - 0.5 * pow_2(L) / TanAlpha; + if (d1 * TanAlpha <= L) { + A1sh = 0.5 * TanAlpha * pow_2(d1); + A2sh = d2 * L - 0.5 * TanAlpha * pow_2(L / TanAlpha - d1); + } else { // d1*TanAlpha > L + A1sh = d1 * L - (0.5 / TanAlpha) * pow_2(L); + A2sh = d2 * L; + } + } + } else { // d2prime > d2 + A2sh = d2 * L; + if (d2prime < d1 + d2) { + if (d12 * TanAlpha <= L) { + A1sh = L * (d2prime - d2) + 0.5 * TanAlpha * pow_2(d12); + } else { // d12*TanAlpha > L + A1sh = d1 * L - 0.5 * pow_2(L) / TanAlpha; + } + } else { // d2prime >= d1+d2 + A1sh = d1 * L; } - } else { // d2prime >= d1+d2 - A1sh = d1 * L; } - } - // Added TH. 5/27/2009 - if (A1sh < 0.0) A1sh = 0.0; - if (A2sh < 0.0) A2sh = 0.0; + // Added TH. 5/27/2009 + if (A1sh < 0.0) A1sh = 0.0; + if (A2sh < 0.0) A2sh = 0.0; - if (OutsReveal >= 0.001) A1ill = d1 * L - A1sh; // A1ill = 0.0 if OutsReveal < 0.001 - if (InsReveal >= 0.001) A2ill = d2 * L - A2sh; // A2ill = 0.0 if InsReveal < 0.001 + if (OutsReveal >= 0.001) A1ill = d1 * L - A1sh; // A1ill = 0.0 if OutsReveal < 0.001 + if (InsReveal >= 0.001) A2ill = d2 * L - A2sh; // A2ill = 0.0 if InsReveal < 0.001 - } else { // Window with frame; take into account shadowing - // of inside reveal surfaces by frame - f1 = d1 - P1; - f2 = d2 - P2; - d2prime2 = FrameWidth / TanGamma; - if (HorVertReveal == 1) { // Vertical reveal - if (InsReveal + 0.5 * GlazingThickness <= P2) d2 = P2 + 0.001; - } else { // Horizontal - if (CosBetaBottom > 0.0) { // Bottom reveal surfaces may be illuminated - if (InsSillDepth + 0.5 * GlazingThickness <= P2) d2 = P2 + 0.001; - } else { // Top reveal surfaces may be illuminated + } else { // Window with frame; take into account shadowing + // of inside reveal surfaces by frame + f1 = d1 - P1; + f2 = d2 - P2; + d2prime2 = FrameWidth / TanGamma; + if (HorVertReveal == 1) { // Vertical reveal if (InsReveal + 0.5 * GlazingThickness <= P2) d2 = P2 + 0.001; + } else { // Horizontal + if (CosBetaBottom > 0.0) { // Bottom reveal surfaces may be illuminated + if (InsSillDepth + 0.5 * GlazingThickness <= P2) d2 = P2 + 0.001; + } else { // Top reveal surfaces may be illuminated + if (InsReveal + 0.5 * GlazingThickness <= P2) d2 = P2 + 0.001; + } } - } - if (d2prime <= f2) { // Shadow from opposing reveal does not go beyond inside surface of frame - - if (d12 * TanAlpha <= L) { - A1sh = 0.5 * TanAlpha * pow_2(f1); - L1 = f1 * (f1 * TanAlpha / (6.0 * L) + 0.5); - if (d2 - (d2prime + d2prime2 + P2) >= 0.0) { - A2sh = (d2prime + d2prime2) * L + 0.5 * TanAlpha * (pow_2(d1 + d2 - d2prime) - pow_2(d1 + P2 + d2prime2)); - L2 = d2prime2 + 0.5 * (d2 - (d2prime + d2prime2 + P2)); - } else { // d2-(d2prime+d2prime2+P2) < 0. ! Inside reveal is fully shadowed by frame and/or opposing reveal - A2sh = f2 * L; - L2 = f2; - } - } else { // d12*TanAlpha >= L - if ((d1 + P2) * TanAlpha <= L) { + if (d2prime <= f2) { // Shadow from opposing reveal does not go beyond inside surface of frame + + if (d12 * TanAlpha <= L) { A1sh = 0.5 * TanAlpha * pow_2(f1); - L1 = f1 * ((f1 * TanAlpha) / (6.0 * L) + 0.5); - if ((d1 + P2 + d2prime2) * TanAlpha >= L) { + L1 = f1 * (f1 * TanAlpha / (6.0 * L) + 0.5); + if (d2 - (d2prime + d2prime2 + P2) >= 0.0) { + A2sh = (d2prime + d2prime2) * L + 0.5 * TanAlpha * (pow_2(d1 + d2 - d2prime) - pow_2(d1 + P2 + d2prime2)); + L2 = d2prime2 + 0.5 * (d2 - (d2prime + d2prime2 + P2)); + } else { // d2-(d2prime+d2prime2+P2) < 0. ! Inside reveal is fully shadowed by + // frame and/or opposing reveal A2sh = f2 * L; L2 = f2; - } else { // (d1+P2+d2prime2)*TanAlpha < L - A2sh = f2 * L - 0.5 * pow_2(L - (d1 + P2) * TanAlpha) / TanAlpha + - d2prime2 * (L - (d1 + P2 + d2prime2 / 2.0) * TanAlpha); - L2 = d2prime2 + (L / TanAlpha - (d1 + P2 + d2prime2)) / 3.0; } - } else { // (d1+P2)*TanAlpha > L - L2 = f2; - A2sh = f2 * L; - if (f1 * TanAlpha <= L) { + } else { // d12*TanAlpha >= L + if ((d1 + P2) * TanAlpha <= L) { A1sh = 0.5 * TanAlpha * pow_2(f1); L1 = f1 * ((f1 * TanAlpha) / (6.0 * L) + 0.5); - } else { // f1*TanAlpha > L - A1sh = f1 * L - 0.5 * pow_2(L) / TanAlpha; - L1 = f1 - (L / TanAlpha) / 3.0; + if ((d1 + P2 + d2prime2) * TanAlpha >= L) { + A2sh = f2 * L; + L2 = f2; + } else { // (d1+P2+d2prime2)*TanAlpha < L + A2sh = f2 * L - 0.5 * pow_2(L - (d1 + P2) * TanAlpha) / TanAlpha + + d2prime2 * (L - (d1 + P2 + d2prime2 / 2.0) * TanAlpha); + L2 = d2prime2 + (L / TanAlpha - (d1 + P2 + d2prime2)) / 3.0; + } + } else { // (d1+P2)*TanAlpha > L + L2 = f2; + A2sh = f2 * L; + if (f1 * TanAlpha <= L) { + A1sh = 0.5 * TanAlpha * pow_2(f1); + L1 = f1 * ((f1 * TanAlpha) / (6.0 * L) + 0.5); + } else { // f1*TanAlpha > L + A1sh = f1 * L - 0.5 * pow_2(L) / TanAlpha; + L1 = f1 - (L / TanAlpha) / 3.0; + } } } - } - - } else { // d2prime > f2 ! Shadow from opposing reveal goes beyond inside of frame - A2sh = f2 * L; - L2 = f2; - if (d2prime >= d1 + d2) { - A1sh = 0.0; - L1 = f1; - } else { // d2prime < d1+d2 - if (d2prime <= d2 + P1) { - if (f1 * TanAlpha <= L) { - A1sh = 0.5 * TanAlpha * pow_2(f1); - L1 = f1 * ((f1 * TanAlpha) / (6.0 * L) + 0.5); - } else { // f1*TanAlpha > L - A1sh = f1 * L - 0.5 * pow_2(L) / TanAlpha; - L1 = f1 - (L / TanAlpha) / 3.0; - } - } else { // d2prime > d2+P1 - if (d12 * TanAlpha <= L) { - A1sh = L * (d2prime - (d2 + P1)) + 0.5 * TanAlpha * pow_2(d12); - L1 = (L * (f1 - d12 / 2.0) - d12 * TanAlpha * (f1 / 2 - d12 / 3.0)) / (L - d12 * TanAlpha / 2.0); - } else { // d12*TanAlpha > L - A1sh = f1 * L - 0.5 * pow_2(L) / TanAlpha; - L1 = f1 - (L / TanAlpha) / 3.0; + } else { // d2prime > f2 ! Shadow from opposing reveal goes beyond inside of frame + + A2sh = f2 * L; + L2 = f2; + if (d2prime >= d1 + d2) { + A1sh = 0.0; + L1 = f1; + } else { // d2prime < d1+d2 + if (d2prime <= d2 + P1) { + if (f1 * TanAlpha <= L) { + A1sh = 0.5 * TanAlpha * pow_2(f1); + L1 = f1 * ((f1 * TanAlpha) / (6.0 * L) + 0.5); + } else { // f1*TanAlpha > L + A1sh = f1 * L - 0.5 * pow_2(L) / TanAlpha; + L1 = f1 - (L / TanAlpha) / 3.0; + } + } else { // d2prime > d2+P1 + if (d12 * TanAlpha <= L) { + A1sh = L * (d2prime - (d2 + P1)) + 0.5 * TanAlpha * pow_2(d12); + L1 = (L * (f1 - d12 / 2.0) - d12 * TanAlpha * (f1 / 2 - d12 / 3.0)) / (L - d12 * TanAlpha / 2.0); + } else { // d12*TanAlpha > L + A1sh = f1 * L - 0.5 * pow_2(L) / TanAlpha; + L1 = f1 - (L / TanAlpha) / 3.0; + } } } } - } - // Added TH. 5/27/2009 - if (A1sh < 0.0) A1sh = 0.0; - if (A2sh < 0.0) A2sh = 0.0; + // Added TH. 5/27/2009 + if (A1sh < 0.0) A1sh = 0.0; + if (A2sh < 0.0) A2sh = 0.0; - if (OutsReveal >= P1 + 0.5 * GlazingThickness + 0.001) A1ill = L * f1 - A1sh; - if (InsReveal >= P2 + 0.5 * GlazingThickness + 0.001) A2ill = L * f2 - A2sh; - if (L1 == 0.0) { - FracToGlassOuts = 0.0; - } else { - FracToGlassOuts = 0.5 * (1.0 - std::atan(FrameWidth / L1) / DataGlobalConstants::PiOvr2); - } - if (L2 == 0.0) { - FracToGlassIns = 0.0; - } else { - FracToGlassIns = 0.5 * (1.0 - std::atan(FrameWidth / L2) / DataGlobalConstants::PiOvr2); - } - } // End of check if window has frame + if (OutsReveal >= P1 + 0.5 * GlazingThickness + 0.001) A1ill = L * f1 - A1sh; + if (InsReveal >= P2 + 0.5 * GlazingThickness + 0.001) A2ill = L * f2 - A2sh; + if (L1 == 0.0) { + FracToGlassOuts = 0.0; + } else { + FracToGlassOuts = 0.5 * (1.0 - std::atan(FrameWidth / L1) / DataGlobalConstants::PiOvr2); + } + if (L2 == 0.0) { + FracToGlassIns = 0.0; + } else { + FracToGlassIns = 0.5 * (1.0 - std::atan(FrameWidth / L2) / DataGlobalConstants::PiOvr2); + } + } // End of check if window has frame - // Added TH. 5/27/2009 - if (A1ill < 0.0) A1ill = 0.0; - if (A2ill < 0.0) A2ill = 0.0; + // Added TH. 5/27/2009 + if (A1ill < 0.0) A1ill = 0.0; + if (A2ill < 0.0) A2ill = 0.0; - // Quantities related to outside reveal - if (A1ill > 1.0e-6) { + // Quantities related to outside reveal + if (A1ill > 1.0e-6) { - state.dataSurface->SurfWinBmSolAbsdOutsReveal(SurfNum) += - A1ill * state.dataSurface->SurfWinOutsideRevealSolAbs(SurfNum) * CosBeta * tmp_SunlitFracWithoutReveal; + state.dataSurface->SurfWinBmSolAbsdOutsReveal(SurfNum) += + A1ill * state.dataSurface->SurfWinOutsideRevealSolAbs(SurfNum) * CosBeta * tmp_SunlitFracWithoutReveal; - BmSolRefldOutsReveal = - A1ill * (1.0 - state.dataSurface->SurfWinOutsideRevealSolAbs(SurfNum)) * CosBeta * tmp_SunlitFracWithoutReveal; + BmSolRefldOutsReveal = + A1ill * (1.0 - state.dataSurface->SurfWinOutsideRevealSolAbs(SurfNum)) * CosBeta * tmp_SunlitFracWithoutReveal; - state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfNum) += state.dataEnvrn->BeamSolarRad * BmSolRefldOutsReveal; - state.dataSurface->SurfWinBmSolRefldOutsRevealRepEnergy(SurfNum) = - state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfNum) * state.dataGlobal->TimeStepZoneSec; + state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfNum) += state.dataEnvrn->BeamSolarRad * BmSolRefldOutsReveal; + state.dataSurface->SurfWinBmSolRefldOutsRevealRepEnergy(SurfNum) = + state.dataSurface->SurfWinBmSolRefldOutsRevealReport(SurfNum) * state.dataGlobal->TimeStepZoneSec; - // Reflected solar from outside horizontal and vertical reveal incident on glazing - state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) += - FracToGlassOuts * BmSolRefldOutsReveal / state.dataSurface->Surface(SurfNum).Area; + // Reflected solar from outside horizontal and vertical reveal incident on glazing + state.dataSurface->SurfWinOutsRevealDiffOntoGlazing(SurfNum) += + FracToGlassOuts * BmSolRefldOutsReveal / state.dataSurface->Surface(SurfNum).Area; - if (FrameWidth > 0.0) { - // Reflected solar from outside horizontal and vertical reveal incident on frame - state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) += - (0.5 - FracToGlassOuts) * BmSolRefldOutsReveal / state.dataSurface->SurfWinFrameArea(SurfNum); - } + if (FrameWidth > 0.0) { + // Reflected solar from outside horizontal and vertical reveal incident on frame + state.dataSurface->SurfWinOutsRevealDiffOntoFrame(SurfNum) += + (0.5 - FracToGlassOuts) * BmSolRefldOutsReveal / state.dataSurface->SurfWinFrameArea(SurfNum); + } - } // End of check if A1ill > 0.0 (actually 10^-6) + } // End of check if A1ill > 0.0 (actually 10^-6) - // Quantities related to inside reveal; inside reveal reflection/absorption is assumed - // to occur only if an interior shade or blind is not in place. + // Quantities related to inside reveal; inside reveal reflection/absorption is assumed + // to occur only if an interior shade or blind is not in place. - if (NOT_SHADED(ShadeFlag) || ShadeFlag == WinShadingType::SwitchableGlazing) { + if (NOT_SHADED(ShadeFlag) || ShadeFlag == WinShadingType::SwitchableGlazing) { - if (A2ill > 1.0e-6) { + if (A2ill > 1.0e-6) { - DiffReflGlass = state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack; - if (ShadeFlag == WinShadingType::SwitchableGlazing) { - SolTransGlassSh = - POLYF(state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum), - state.dataConstruction->Construct(ConstrNumSh).TransSolBeamCoef); - SolTransGlass = InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum), SolTransGlass, SolTransGlassSh); - DiffReflGlassSh = state.dataConstruction->Construct(ConstrNumSh).ReflectSolDiffBack; - DiffReflGlass = InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum), DiffReflGlass, DiffReflGlassSh); - } + DiffReflGlass = state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack; + if (ShadeFlag == WinShadingType::SwitchableGlazing) { + SolTransGlassSh = + POLYF(state.dataHeatBal->SurfCosIncAng(state.dataGlobal->HourOfDay, state.dataGlobal->TimeStep, SurfNum), + state.dataConstruction->Construct(ConstrNumSh).TransSolBeamCoef); + SolTransGlass = InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum), SolTransGlass, SolTransGlassSh); + DiffReflGlassSh = state.dataConstruction->Construct(ConstrNumSh).ReflectSolDiffBack; + DiffReflGlass = InterpSw(state.dataSurface->SurfWinSwitchingFactor(SurfNum), DiffReflGlass, DiffReflGlassSh); + } - // Calc beam solar sbsorbed (m2) - state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) += - A2ill * SolTransGlass * InsideRevealSolAbs * CosBeta * tmp_SunlitFracWithoutReveal; + // Calc beam solar sbsorbed (m2) + state.dataSurface->SurfWinBmSolAbsdInsReveal(SurfNum) += + A2ill * SolTransGlass * InsideRevealSolAbs * CosBeta * tmp_SunlitFracWithoutReveal; - // Added TH 5/26/2009 for reporting purpose - Beam solar absorbed by the inside reveal (W) - state.dataSurface->SurfWinBmSolAbsdInsRevealReport(SurfNum) += - state.dataEnvrn->BeamSolarRad * A2ill * SolTransGlass * InsideRevealSolAbs * CosBeta * tmp_SunlitFracWithoutReveal; + // Added TH 5/26/2009 for reporting purpose - Beam solar absorbed by the inside reveal + // (W) + state.dataSurface->SurfWinBmSolAbsdInsRevealReport(SurfNum) += + state.dataEnvrn->BeamSolarRad * A2ill * SolTransGlass * InsideRevealSolAbs * CosBeta * tmp_SunlitFracWithoutReveal; - // in m2 = Area * solar transmitted fraction * inside reveal reflection fraction - BmSolRefldInsReveal = A2ill * SolTransGlass * (1.0 - InsideRevealSolAbs) * CosBeta * tmp_SunlitFracWithoutReveal; + // in m2 = Area * solar transmitted fraction * inside reveal reflection fraction + BmSolRefldInsReveal = A2ill * SolTransGlass * (1.0 - InsideRevealSolAbs) * CosBeta * tmp_SunlitFracWithoutReveal; - state.dataSurface->SurfWinBmSolRefldInsReveal(SurfNum) += BmSolRefldInsReveal; + state.dataSurface->SurfWinBmSolRefldInsReveal(SurfNum) += BmSolRefldInsReveal; - state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfNum) += - state.dataEnvrn->BeamSolarRad * BmSolRefldInsReveal; // W, BeamSolarRad in W/m2 - state.dataSurface->SurfWinBmSolRefldInsRevealRepEnergy(SurfNum) = - state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfNum) * state.dataGlobal->TimeStepZoneSec; + state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfNum) += + state.dataEnvrn->BeamSolarRad * BmSolRefldInsReveal; // W, BeamSolarRad in W/m2 + state.dataSurface->SurfWinBmSolRefldInsRevealRepEnergy(SurfNum) = + state.dataSurface->SurfWinBmSolRefldInsRevealReport(SurfNum) * state.dataGlobal->TimeStepZoneSec; - // Reflected solar from inside horizontal and vertical reveal incident on glazing - state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum) += - FracToGlassIns * BmSolRefldInsReveal / state.dataSurface->Surface(SurfNum).Area; + // Reflected solar from inside horizontal and vertical reveal incident on glazing + state.dataSurface->SurfWinInsRevealDiffOntoGlazing(SurfNum) += + FracToGlassIns * BmSolRefldInsReveal / state.dataSurface->Surface(SurfNum).Area; - // Added TH 5/26/2009 for reporting purpose - diffuse on window glass from inside reveal (W) - state.dataSurface->SurfWinInsRevealDiffOntoGlazingReport(SurfNum) += - state.dataEnvrn->BeamSolarRad * FracToGlassIns * BmSolRefldInsReveal; + // Added TH 5/26/2009 for reporting purpose - diffuse on window glass from inside + // reveal (W) + state.dataSurface->SurfWinInsRevealDiffOntoGlazingReport(SurfNum) += + state.dataEnvrn->BeamSolarRad * FracToGlassIns * BmSolRefldInsReveal; - // Reflected solar from inside horizontal and vertical reveal incident on frame - if (FrameWidth > 0.0) { - state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) += - (0.5 - FracToGlassIns) * BmSolRefldInsReveal / state.dataSurface->SurfWinFrameArea(SurfNum); + // Reflected solar from inside horizontal and vertical reveal incident on frame + if (FrameWidth > 0.0) { + state.dataSurface->SurfWinInsRevealDiffOntoFrame(SurfNum) += + (0.5 - FracToGlassIns) * BmSolRefldInsReveal / state.dataSurface->SurfWinFrameArea(SurfNum); - // Added TH 5/26/2009 for reporting purpose - diffuse on window frame from inside reveal (W) - state.dataSurface->SurfWinInsRevealDiffOntoFrameReport(SurfNum) += - state.dataEnvrn->BeamSolarRad * (0.5 - FracToGlassIns) * BmSolRefldInsReveal; - } + // Added TH 5/26/2009 for reporting purpose - diffuse on window frame from inside + // reveal (W) + state.dataSurface->SurfWinInsRevealDiffOntoFrameReport(SurfNum) += + state.dataEnvrn->BeamSolarRad * (0.5 - FracToGlassIns) * BmSolRefldInsReveal; + } - // Reflected solar from inside reveal going directly into zone and reflected from glass. - // Assumes half of solar reflected from inside reveal goes as diffuse radiation into the zone and - // half goes as diffuse radiation towards window. - state.dataSurface->SurfWinInsRevealDiffIntoZone(SurfNum) += BmSolRefldInsReveal * (0.5 + DiffReflGlass * FracToGlassIns); + // Reflected solar from inside reveal going directly into zone and reflected from + // glass. Assumes half of solar reflected from inside reveal goes as diffuse radiation + // into the zone and half goes as diffuse radiation towards window. + state.dataSurface->SurfWinInsRevealDiffIntoZone(SurfNum) += BmSolRefldInsReveal * (0.5 + DiffReflGlass * FracToGlassIns); - // Added TH 5/26/2009 for reporting purpose - diffuse into zone from inside reveal (W) - state.dataSurface->SurfWinInsRevealDiffIntoZoneReport(SurfNum) += - state.dataEnvrn->BeamSolarRad * BmSolRefldInsReveal * (0.5 + DiffReflGlass * FracToGlassIns); + // Added TH 5/26/2009 for reporting purpose - diffuse into zone from inside reveal (W) + state.dataSurface->SurfWinInsRevealDiffIntoZoneReport(SurfNum) += + state.dataEnvrn->BeamSolarRad * BmSolRefldInsReveal * (0.5 + DiffReflGlass * FracToGlassIns); - } // End of check if A2ill > 0.0 (actually 10^-6) + } // End of check if A2ill > 0.0 (actually 10^-6) - } // End of check if interior shade or blind is in place + } // End of check if interior shade or blind is in place - } // End of loop over vertical and horizontal reveal - } + } // End of loop over vertical and horizontal reveal - } // End of surface loop + } // End of surface loop + } + } } void ReportSurfaceShading(EnergyPlusData &state) @@ -11432,9 +11483,9 @@ void ReportSurfaceErrors(EnergyPlusData &state) if (state.dataSolarShading->NumBaseSubSurround > 0) { ShowMessage(state, "Base Surface does not surround subsurface errors occurring..."); - ShowMessage( - state, - "Check that the GlobalGeometryRules object is expressing the proper starting corner and direction [CounterClockwise/Clockwise]"); + ShowMessage(state, + "Check that the GlobalGeometryRules object is expressing the proper starting corner and " + "direction [CounterClockwise/Clockwise]"); ShowMessage(state, ""); } @@ -11480,7 +11531,8 @@ void ReportSurfaceErrors(EnergyPlusData &state) if (state.dataSolarShading->NumTooManyVertices > 0) { ShowMessage(state, format("Too many vertices [>={}] in shadow overlap errors occurring...", state.dataSolarShading->MaxHCV)); ShowMessage(state, - "These occur throughout the year and may occur several times for the same surfaces. You may be able to reduce them by " + "These occur throughout the year and may occur several times for the same surfaces. You " + "may be able to reduce them by " "adding Output:Diagnostics,DoNotMirrorDetachedShading;"); } for (Loop1 = 1; Loop1 <= state.dataSolarShading->NumTooManyVertices; ++Loop1) { @@ -11528,7 +11580,8 @@ void ReportSurfaceErrors(EnergyPlusData &state) if (state.dataSolarShading->NumTooManyFigures > 0) { ShowMessage(state, format("Too many figures [>={}] in shadow overlap errors occurring...", state.dataSolarShading->MaxHCS)); ShowMessage(state, - "These occur throughout the year and may occur several times for the same surfaces. You may be able to reduce them by " + "These occur throughout the year and may occur several times for the same surfaces. You " + "may be able to reduce them by " "adding OutputDiagnostics,DoNotMirrorDetachedShading;"); } for (Loop1 = 1; Loop1 <= state.dataSolarShading->NumTooManyFigures; ++Loop1) { @@ -11579,7 +11632,8 @@ void ComputeWinShadeAbsorpFactors(EnergyPlusData &state) // SUBROUTINE INFORMATION: // AUTHOR Fred Winkelmann // DATE WRITTEN Mar 2001 - // MODIFIED Oct 2002,FCW: change ConstrNumSh = WindowShadingControl(WinShadeCtrlNum)%ShadedConstruction + // MODIFIED Oct 2002,FCW: change ConstrNumSh = + // WindowShadingControl(WinShadeCtrlNum)%ShadedConstruction // to Surface(SurfNum)%ShadedConstruction // RE-ENGINEERED na @@ -11594,39 +11648,42 @@ void ComputeWinShadeAbsorpFactors(EnergyPlusData &state) // USE STATEMENTS: na for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceFirst; - int const lastSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceLast; - for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { - if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Window && state.dataSurface->Surface(SurfNum).HasShadeControl) { - int WinShadeCtrlNum = state.dataSurface->Surface(SurfNum).activeWindowShadingControl; // Window shading control number - - int MatNumSh = 0; // Shade layer material number - Real64 AbsorpEff = 0.0; // Effective absorptance of isolated shade layer (fraction of - // of incident radiation remaining after reflected portion is - // removed that is absorbed - if (ANY_SHADE(state.dataSurface->WindowShadingControl(WinShadeCtrlNum).ShadingType)) { - int const ConstrNumSh = state.dataSurface->Surface(SurfNum).activeShadedConstruction; // Window construction number with shade - int TotLay = state.dataConstruction->Construct(ConstrNumSh).TotLayers; // Total layers in a construction - - if (state.dataSurface->WindowShadingControl(WinShadeCtrlNum).ShadingType == WinShadingType::IntShade) { - MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(TotLay); // Interior shade - } else if (state.dataSurface->WindowShadingControl(WinShadeCtrlNum).ShadingType == WinShadingType::ExtShade) { - MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(1); // Exterior shade - } else if (state.dataSurface->WindowShadingControl(WinShadeCtrlNum).ShadingType == WinShadingType::BGShade) { - if (state.dataConstruction->Construct(ConstrNumSh).TotGlassLayers == 2) { - // Double pane with between-glass shade - MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(3); - } else { - // Triple pane with between-glass shade - MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(5); + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurfWin = thisSpace.WindowSurfaceFirst; + int const lastSurfWin = thisSpace.WindowSurfaceLast; + for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { + if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Window && state.dataSurface->Surface(SurfNum).HasShadeControl) { + int WinShadeCtrlNum = state.dataSurface->Surface(SurfNum).activeWindowShadingControl; // Window shading control number + + int MatNumSh = 0; // Shade layer material number + Real64 AbsorpEff = 0.0; // Effective absorptance of isolated shade layer (fraction of + // of incident radiation remaining after reflected portion is + // removed that is absorbed + if (ANY_SHADE(state.dataSurface->WindowShadingControl(WinShadeCtrlNum).ShadingType)) { + int const ConstrNumSh = state.dataSurface->Surface(SurfNum).activeShadedConstruction; // Window construction number with shade + int TotLay = state.dataConstruction->Construct(ConstrNumSh).TotLayers; // Total layers in a construction + + if (state.dataSurface->WindowShadingControl(WinShadeCtrlNum).ShadingType == WinShadingType::IntShade) { + MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(TotLay); // Interior shade + } else if (state.dataSurface->WindowShadingControl(WinShadeCtrlNum).ShadingType == WinShadingType::ExtShade) { + MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(1); // Exterior shade + } else if (state.dataSurface->WindowShadingControl(WinShadeCtrlNum).ShadingType == WinShadingType::BGShade) { + if (state.dataConstruction->Construct(ConstrNumSh).TotGlassLayers == 2) { + // Double pane with between-glass shade + MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(3); + } else { + // Triple pane with between-glass shade + MatNumSh = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(5); + } } + AbsorpEff = state.dataMaterial->Material(MatNumSh).AbsorpSolar / + (state.dataMaterial->Material(MatNumSh).AbsorpSolar + state.dataMaterial->Material(MatNumSh).Trans + 0.0001); + AbsorpEff = min(max(AbsorpEff, 0.0001), + 0.999); // Constrain to avoid problems with following log eval + state.dataSurface->SurfWinShadeAbsFacFace1(SurfNum) = (1.0 - std::exp(0.5 * std::log(1.0 - AbsorpEff))) / AbsorpEff; + state.dataSurface->SurfWinShadeAbsFacFace2(SurfNum) = 1.0 - state.dataSurface->SurfWinShadeAbsFacFace1(SurfNum); } - AbsorpEff = state.dataMaterial->Material(MatNumSh).AbsorpSolar / - (state.dataMaterial->Material(MatNumSh).AbsorpSolar + state.dataMaterial->Material(MatNumSh).Trans + 0.0001); - AbsorpEff = min(max(AbsorpEff, 0.0001), - 0.999); // Constrain to avoid problems with following log eval - state.dataSurface->SurfWinShadeAbsFacFace1(SurfNum) = (1.0 - std::exp(0.5 * std::log(1.0 - AbsorpEff))) / AbsorpEff; - state.dataSurface->SurfWinShadeAbsFacFace2(SurfNum) = 1.0 - state.dataSurface->SurfWinShadeAbsFacFace1(SurfNum); } } } @@ -11681,8 +11738,9 @@ void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state) Real64 ViewFactor; // temp var for view factor // Real64 ViewFactorTotal; // debug var for view factor total Real64 WinDifSolarTrans; // debug var for WinDifSolar() [W] - // Real64 WinDifSolarDistTotl; // debug var for window total distributed diffuse solar [W] - // Real64 WinDifSolarDistAbsorbedTotl; // debug var for individual exterior window total distributed + // Real64 WinDifSolarDistTotl; // debug var for window total + // distributed diffuse solar [W] Real64 WinDifSolarDistAbsorbedTotl; // debug + // var for individual exterior window total distributed // diffuse solar absorbed [W] // Real64 WinDifSolarDistReflectedTotl; // debug var for individual exterior window total distributed // diffuse solar reflected [W] @@ -11690,10 +11748,12 @@ void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state) // diffuse solar transmitted [W] Real64 WinDifSolLayAbsW; // temp var for diffuse solar absorbed by individual glass layer [W] // Real64 ZoneDifSolarTrans; // debug var for WinDifSolar() [W] - // Real64 ZoneDifSolarDistTotl; // debug var for zone total distributed diffuse solar [W] - // Real64 ZoneDifSolarDistAbsorbedTotl; // debug var for zone total distributed diffuse solar absorbed [W] - // Real64 ZoneDifSolarDistReflectedTotl; // debug var for zone total distributed diffuse solar reflected [W] - // Real64 ZoneDifSolarDistTransmittedTotl; // debug var for zone total distributed diffuse solar transmitted [W] + // Real64 ZoneDifSolarDistTotl; // debug var for zone total + // distributed diffuse solar [W] Real64 ZoneDifSolarDistAbsorbedTotl; // + // debug var for zone total distributed diffuse solar absorbed [W] Real64 + // ZoneDifSolarDistReflectedTotl; // debug var for zone total distributed + // diffuse solar reflected [W] Real64 ZoneDifSolarDistTransmittedTotl; // + // debug var for zone total distributed diffuse solar transmitted [W] Real64 DifSolarAbsW; // temp var for diffuse solar absorbed by surface [W] Real64 DifSolarAbs; // temp var for diffuse solar absorbed by surface [W/m2] @@ -11701,8 +11761,9 @@ void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state) Real64 DifSolarTransW; // temp var for diffuse solar transmitted through interior window surface [W] Real64 ShBlDifSolarAbsW; // temp var for diffuse solar absorbed by shade/blind [W] - Array2D SurfWinAbsSolBeamEQL(2, CFSMAXNL + 1); // absorbed exterior beam radiation by layers fraction - Array2D SurfWinAbsSolDiffEQL(2, CFSMAXNL + 1); // absorbed exterior diffuse radiation by layers fraction + Array2D SurfWinAbsSolBeamEQL(2, CFSMAXNL + 1); // absorbed exterior beam radiation by layers fraction + Array2D SurfWinAbsSolDiffEQL(2, + CFSMAXNL + 1); // absorbed exterior diffuse radiation by layers fraction Array2D SurfWinAbsSolBeamBackEQL(2, CFSMAXNL + 1); // absorbed interior beam radiation by layers fraction from back Array2D AbsSolDiffBackEQL(2, CFSMAXNL + 1); // absorbed exterior diffuse radiation by layers fraction from back int EQLNum; // equivalent layer fenestration index @@ -11735,7 +11796,8 @@ void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state) continue; // Do I need to do anything special for TDDs? - // if ( SurfaceWindow( DifTransSurfNum ).OriginalClass == SurfaceClass::TDD_Diffuser ) { + // if ( SurfaceWindow( DifTransSurfNum ).OriginalClass == SurfaceClass::TDD_Diffuser ) + // { // } // Skip surfaces that are not exterior windows or TDD diffusers @@ -11744,7 +11806,8 @@ void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state) continue; //---------------------------------------------------------------------------------------------------------- - // DISTRIBUTE TRANSMITTED DIFFUSE SOLAR THROUGH EXTERIOR WINDOWS AND TDDS TO INTERIOR HEAT TRANSFER SURFACES + // DISTRIBUTE TRANSMITTED DIFFUSE SOLAR THROUGH EXTERIOR WINDOWS AND TDDS TO INTERIOR HEAT TRANSFER + // SURFACES //---------------------------------------------------------------------------------------------------------- // Init transmitted solar debug vars @@ -11763,7 +11826,8 @@ void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state) // Skip tubular daylighting device domes if (state.dataSurface->Surface(HeatTransSurfNum).Class == SurfaceClass::TDD_Dome) continue; - // View factor from current (sending) window DifTransSurfNum to current (receiving) surface HeatTransSurfNum + // View factor from current (sending) window DifTransSurfNum to current (receiving) surface + // HeatTransSurfNum int const HTenclosureSurfNum = state.dataSurface->Surface(HeatTransSurfNum).SolarEnclSurfIndex; // HT surface index for EnclSolInfo.SurfacePtr and F arrays int const enclosureNum = state.dataSurface->Surface(HeatTransSurfNum).SolarEnclIndex; // index for EnclSolInfo @@ -11781,8 +11845,9 @@ void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state) Real64 const win_SwitchingFactor(state.dataSurface->SurfWinSwitchingFactor(HeatTransSurfNum)); Real64 const per_HTSurfaceArea(1.0 / state.dataSurface->Surface(HeatTransSurfNum).Area); - // Calculate diffuse solar from current exterior window absorbed and reflected by current heat transfer surface - // And calculate transmitted diffuse solar to adjacent zones through interior windows + // Calculate diffuse solar from current exterior window absorbed and reflected by current heat + // transfer surface And calculate transmitted diffuse solar to adjacent zones through interior + // windows int const ConstrNum = state.dataSurface->SurfActiveConstruction(HeatTransSurfNum); if (state.dataConstruction->Construct(ConstrNum).TransDiff <= 0.0) { // Interior Opaque Surface @@ -11793,7 +11858,8 @@ void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state) InsideDifReflectance = 1.0 - InsideDifAbsorptance; // Absorbed diffuse solar [W] = current window transmitted diffuse solar [W] - // * view factor from current (sending) window DifTransSurfNum to current (receiving) surface HeatTransSurfNum + // * view factor from current (sending) window DifTransSurfNum to current (receiving) + // surface HeatTransSurfNum // * current surface inside solar absorptance DifSolarAbsW = WinDifSolarTrans_Factor * InsideDifAbsorptance; // [W] @@ -11805,15 +11871,17 @@ void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state) state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(HeatTransSurfNum) += DifSolarAbs; // Reflected diffuse solar [W] = current window transmitted diffuse solar - // * view factor from current (sending) window DifTransSurfNum to current (receiving) surface HeatTransSurfNum + // * view factor from current (sending) window DifTransSurfNum to current (receiving) + // surface HeatTransSurfNum // * current window inside solar reflectance DifSolarReflW = WinDifSolarTrans_Factor * InsideDifReflectance; - // Accumulate total reflected distributed diffuse solar for each zone for subsequent interreflection calcs + // Accumulate total reflected distributed diffuse solar for each zone for subsequent + // interreflection calcs state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum) += DifSolarReflW; // [W] - // Accumulate Window and Zone total distributed diffuse solar to check for conservation of energy - // For opaque surfaces all incident diffuse is either absorbed or reflected + // Accumulate Window and Zone total distributed diffuse solar to check for conservation of + // energy For opaque surfaces all incident diffuse is either absorbed or reflected } else { // Exterior or Interior Window int const ConstrNumSh = state.dataSurface->SurfWinActiveShadedConstruction(HeatTransSurfNum); @@ -11826,30 +11894,35 @@ void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state) DifSolarAbsW = 0.0; // Calc diffuse solar absorbed by all window glass layers - // Note: I am assuming here that individual glass layer absorptances have been corrected + // Note: I am assuming here that individual glass layer absorptances have been + // corrected // to account for layer by layer transmittance and reflection effects. for (int IGlass = 1; IGlass <= TotGlassLayers; ++IGlass) { // Calc diffuse solar absorbed from the inside by each window glass layer [W] AbsInt = state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass); WinDifSolLayAbsW = WinDifSolarTrans_Factor * state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass); - // Accumulate distributed diffuse solar absorbed [W] by overall window for transmittance calc below + // Accumulate distributed diffuse solar absorbed [W] by overall window for + // transmittance calc below DifSolarAbsW += WinDifSolLayAbsW; - // Accumulate diffuse solar absorbed from the inside by each window glass layer [W/m2] for heat balance calcs + // Accumulate diffuse solar absorbed from the inside by each window glass layer + // [W/m2] for heat balance calcs state.dataHeatBal->SurfWinInitialDifSolwinAbs(HeatTransSurfNum, IGlass) += WinDifSolLayAbsW * per_HTSurfaceArea; } // Calc diffuse solar reflected back to zone // I don't really care if this is a window or opaque surface since I am just - // accumulating all reflected diffuse solar in a zone bucket for "interreflected" distribution - // Reflected diffuse solar [W] = current window transmitted diffuse solar - // * view factor from current (sending) window DifTransSurfNum to current (receiving) surface HeatTransSurfNum + // accumulating all reflected diffuse solar in a zone bucket for "interreflected" + // distribution Reflected diffuse solar [W] = current window transmitted diffuse solar + // * view factor from current (sending) window DifTransSurfNum to current + // (receiving) surface HeatTransSurfNum // * current window inside solar reflectance InsideDifReflectance = state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack; DifSolarReflW = WinDifSolarTrans_Factor * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack; - // Accumulate total reflected distributed diffuse solar for each zone for subsequent interreflection calcs + // Accumulate total reflected distributed diffuse solar for each zone for subsequent + // interreflection calcs state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum) += DifSolarReflW; // [W] //------------------------------------------------------------------------------ @@ -11858,7 +11931,8 @@ void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state) // If this receiving window surface (HeatTransSurfNum) is an interior window, // calc distributed solar transmitted to adjacent zone [W] - // NOTE: This calc is here because interior windows are currently assumed to have no shading + // NOTE: This calc is here because interior windows are currently assumed to have no + // shading // Get the adjacent surface number for this receiving window surface int AdjSurfNum = state.dataSurface->Surface(HeatTransSurfNum).ExtBoundCond; @@ -11867,17 +11941,21 @@ void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state) // Calc diffuse solar from current exterior window // transmitted through this interior window to adjacent zone [W] - // Transmitted diffuse solar [W] = current exterior window transmitted diffuse solar - // * view factor from current (sending) window DifTransSurfNum to current (receiving) surface HeatTransSurfNum + // Transmitted diffuse solar [W] = current exterior window transmitted diffuse + // solar + // * view factor from current (sending) window DifTransSurfNum to current + // (receiving) surface HeatTransSurfNum // - diffuse absorbed by this interior window // - diffuse reflected by this interior window DifSolarTransW = WinDifSolarTrans_Factor - DifSolarAbsW - DifSolarReflW; - // HERE 8/15/07 Note Construct(AdjConstrNum)%TransDiff could be used here since the "front" transmittance for an - // interior window in the adjacent zone is the correct direction as long as I use the Construct() of the Surface - // in the adjacent zone. However, the above calculation better conserves energy, although possibly at the expense - // of less accurate transmittance calcs. Preliminary tests showed fairly good agreement between the two - // DifSolarTransW calculation methods, but for consistency I stuck with the above. - // int AdjConstrNum = Surface(AdjSurfNum).Construction; + // HERE 8/15/07 Note Construct(AdjConstrNum)%TransDiff could be used here since + // the "front" transmittance for an interior window in the adjacent zone is the + // correct direction as long as I use the Construct() of the Surface in the + // adjacent zone. However, the above calculation better conserves energy, although + // possibly at the expense of less accurate transmittance calcs. Preliminary tests + // showed fairly good agreement between the two DifSolarTransW calculation + // methods, but for consistency I stuck with the above. int AdjConstrNum = + // Surface(AdjSurfNum).Construction; // DifSolarTransW = WinDifSolar(DifTransSurfNum) & // * ViewFactor & // * Construct(AdjConstrNum)%TransDiff @@ -11885,14 +11963,15 @@ void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state) // Get the adjacent zone index int const adjEnclosureNum = state.dataSurface->Surface(AdjSurfNum).SolarEnclIndex; - // Call routine to distribute diffuse solar transmitted through this interior window into adjacent zone + // Call routine to distribute diffuse solar transmitted through this interior + // window into adjacent zone CalcInteriorWinTransDifSolInitialDistribution(state, adjEnclosureNum, AdjSurfNum, DifSolarTransW); } else { // this is an exterior window surface - // Calc transmitted Window and Zone total distributed diffuse solar to check for conservation of energy - // This is not very effective since it assigns whatever distributed diffuse solar has not been - // absorbed or reflected to transmitted. + // Calc transmitted Window and Zone total distributed diffuse solar to check for + // conservation of energy This is not very effective since it assigns whatever + // distributed diffuse solar has not been absorbed or reflected to transmitted. DifSolarTransW = WinDifSolarTrans_Factor - DifSolarAbsW - DifSolarReflW; } // this is an interior window surface @@ -11913,10 +11992,12 @@ void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state) WinDifSolLayAbsW = WinDifSolarTrans_Factor * InterpSw(win_SwitchingFactor, construct_AbsDiffBack(IGlass), construct_sh_AbsDiffBack(IGlass)); - // Accumulate distributed diffuse solar absorbed [W] by overall window for transmittance calc below + // Accumulate distributed diffuse solar absorbed [W] by overall window for + // transmittance calc below DifSolarAbsW += WinDifSolLayAbsW; - // Accumulate diffuse solar absorbed from the inside by each window glass layer [W/m2] for heat balance calcs + // Accumulate diffuse solar absorbed from the inside by each window glass layer + // [W/m2] for heat balance calcs state.dataHeatBal->SurfWinInitialDifSolwinAbs(HeatTransSurfNum, IGlass) += WinDifSolLayAbsW * per_HTSurfaceArea; } @@ -11924,12 +12005,13 @@ void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state) DifSolarReflW = WinDifSolarTrans_Factor * InterpSw(win_SwitchingFactor, construct.ReflectSolDiffBack, construct_sh.ReflectSolDiffBack); - // Accumulate total reflected distributed diffuse solar for each zone for subsequent interreflection calcs + // Accumulate total reflected distributed diffuse solar for each zone for subsequent + // interreflection calcs state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum) += DifSolarReflW; // [W] - // Accumulate transmitted Window and Zone total distributed diffuse solar to check for conservation of energy - // This is not very effective since it assigns whatever distributed diffuse solar has not been - // absorbed or reflected to transmitted. + // Accumulate transmitted Window and Zone total distributed diffuse solar to check for + // conservation of energy This is not very effective since it assigns whatever + // distributed diffuse solar has not been absorbed or reflected to transmitted. DifSolarTransW = WinDifSolarTrans_Factor - DifSolarAbsW - DifSolarReflW; // Accumulate transmitted diffuse solar for reporting @@ -11942,7 +12024,8 @@ void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state) DifSolarAbsW = 0.0; WinDifSolLayAbsW = 0.0; - // First calc diffuse solar absorbed by each glass layer in this window with shade/blind in place + // First calc diffuse solar absorbed by each glass layer in this window with + // shade/blind in place auto const &construct_sh(state.dataConstruction->Construct(ConstrNumSh)); auto const &construct_sh_AbsDiffBack(construct_sh.AbsDiffBack); auto const &construct_sh_BlAbsDiffBack(construct_sh.BlAbsDiffBack); @@ -11967,10 +12050,12 @@ void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state) WinDifSolLayAbsW = WinDifSolarTrans_Factor * BlAbsDiffBk; } - // Accumulate distributed diffuse solar absorbed [W] by overall window for transmittance calc below + // Accumulate distributed diffuse solar absorbed [W] by overall window for + // transmittance calc below DifSolarAbsW += WinDifSolLayAbsW; - // Accumulate diffuse solar absorbed from the inside by each window glass layer [W/m2] for heat balance calcs + // Accumulate diffuse solar absorbed from the inside by each window glass layer + // [W/m2] for heat balance calcs state.dataHeatBal->SurfWinInitialDifSolwinAbs(HeatTransSurfNum, IGlass) += WinDifSolLayAbsW * per_HTSurfaceArea; } @@ -11991,7 +12076,8 @@ void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state) } DifSolarReflW = WinDifSolarTrans_Factor * InsideDifReflectance; - // Accumulate total reflected distributed diffuse solar for each zone for subsequent interreflection calcs + // Accumulate total reflected distributed diffuse solar for each zone for subsequent + // interreflection calcs state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum) += DifSolarReflW; // [W] // Now calc diffuse solar absorbed by shade/blind itself @@ -12019,12 +12105,13 @@ void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state) // Accumulate diffuse solar absorbed by shade or screen [W/m2] for heat balance calcs state.dataSurface->SurfWinInitialDifSolAbsByShade(HeatTransSurfNum) += ShBlDifSolarAbsW * per_HTSurfaceArea; - // Accumulate distributed diffuse solar absorbed [W] by overall window for transmittance calc below + // Accumulate distributed diffuse solar absorbed [W] by overall window for + // transmittance calc below DifSolarAbsW += ShBlDifSolarAbsW; - // Accumulate transmitted Window and Zone total distributed diffuse solar to check for conservation of energy - // This is not very effective since it assigns whatever distributed diffuse solar has not been - // absorbed or reflected to transmitted. + // Accumulate transmitted Window and Zone total distributed diffuse solar to check for + // conservation of energy This is not very effective since it assigns whatever + // distributed diffuse solar has not been absorbed or reflected to transmitted. DifSolarTransW = WinDifSolarTrans_Factor - DifSolarAbsW - DifSolarReflW; // Accumulate transmitted diffuse solar for reporting @@ -12041,29 +12128,35 @@ void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state) for (Lay = 1; Lay <= state.dataWindowEquivLayer->CFS(EQLNum).NL; ++Lay) { // Calc diffuse solar absorbed from the inside by each layer of EQL model [W] - // WinDifSolLayAbsW = WinDifSolar(DifTransSurfNum)* ViewFactor * Construct(ConstrNum)%AbsDiffBack(Lay) + // WinDifSolLayAbsW = WinDifSolar(DifTransSurfNum)* ViewFactor * + // Construct(ConstrNum)%AbsDiffBack(Lay) WinDifSolLayAbsW = WinDifSolarTrans_Factor * AbsSolDiffBackEQL(2, Lay); - // Accumulate distributed diffuse solar absorbed [W] by overall window for transmittance calc below + // Accumulate distributed diffuse solar absorbed [W] by overall window for + // transmittance calc below DifSolarAbsW += WinDifSolLayAbsW; - // Accumulate diffuse solar absorbed from the inside by each window layer [W/m2] for heat balance calcs + // Accumulate diffuse solar absorbed from the inside by each window layer [W/m2] for + // heat balance calcs state.dataHeatBal->SurfWinInitialDifSolwinAbs(HeatTransSurfNum, Lay) += WinDifSolLayAbsW * per_HTSurfaceArea; - // ASHWAT equivalent layer model may require not the individual layer absorption but the flux - // InitialDifSolwinEQL(HeatTransSurfNum) = WinDifSolar(DifTransSurfNum)* ViewFactor + // ASHWAT equivalent layer model may require not the individual layer absorption but + // the flux InitialDifSolwinEQL(HeatTransSurfNum) = WinDifSolar(DifTransSurfNum)* + // ViewFactor } // Calc diffuse solar reflected back to zone // I don't really care if this is a window or opaque surface since I am just - // accumulating all reflected diffuse solar in a zone bucket for "interreflected" distribution - // Reflected diffuse solar [W] = current window transmitted diffuse solar - // * view factor from current (sending) window DifTransSurfNum to current (receiving) surface HeatTransSurfNum + // accumulating all reflected diffuse solar in a zone bucket for "interreflected" + // distribution Reflected diffuse solar [W] = current window transmitted diffuse solar + // * view factor from current (sending) window DifTransSurfNum to current (receiving) + // surface HeatTransSurfNum // * current window inside solar reflectance InsideDifReflectance = state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack; DifSolarReflW = WinDifSolarTrans_Factor * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack; - // Accumulate total reflected distributed diffuse solar for each zone for subsequent interreflection calcs + // Accumulate total reflected distributed diffuse solar for each zone for subsequent + // interreflection calcs state.dataHeatBal->EnclSolInitialDifSolReflW(enclosureNum) += DifSolarReflW; // [W] //------------------------------------------------------------------------------ @@ -12072,7 +12165,8 @@ void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state) // If this receiving window surface (HeatTransSurfNum) is an interior window, // calc distributed solar transmitted to adjacent zone [W] - // NOTE: This calc is here because interior windows are currently assumed to have no shading + // NOTE: This calc is here because interior windows are currently assumed to have no + // shading // Get the adjacent surface number for this receiving window surface int const AdjSurfNum = state.dataSurface->Surface(HeatTransSurfNum).ExtBoundCond; @@ -12082,19 +12176,21 @@ void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state) // Calc diffuse solar from current exterior window // transmitted through this interior window to adjacent zone [W] // Transmitted diffuse solar [W] = current exterior window transmitted diffuse solar - // * view factor from current (sending) window DifTransSurfNum to current (receiving) surface HeatTransSurfNum + // * view factor from current (sending) window DifTransSurfNum to current + // (receiving) surface HeatTransSurfNum DifSolarTransW = AbsSolDiffBackEQL(2, state.dataWindowEquivLayer->CFS(EQLNum).NL + 1) * ViewFactor; // int AdjConstrNum = Surface(AdjSurfNum).Construction; // Get the adjacent zone index int adjEnclosureNum = state.dataSurface->Surface(AdjSurfNum).SolarEnclIndex; - // Call routine to distribute diffuse solar transmitted through this interior window into adjacent zone + // Call routine to distribute diffuse solar transmitted through this interior window + // into adjacent zone CalcInteriorWinTransDifSolInitialDistribution(state, adjEnclosureNum, AdjSurfNum, DifSolarTransW); } else { // this is an exterior window surface - // Calc transmitted Window and Zone total distributed diffuse solar to check for conservation of energy - // This is not very effective since it assigns whatever distributed diffuse solar has not been - // absorbed or reflected to transmitted. + // Calc transmitted Window and Zone total distributed diffuse solar to check for + // conservation of energy This is not very effective since it assigns whatever + // distributed diffuse solar has not been absorbed or reflected to transmitted. DifSolarTransW = AbsSolDiffBackEQL(2, state.dataWindowEquivLayer->CFS(EQLNum).NL + 1) * ViewFactor; } // this is an interior window surface @@ -12114,20 +12210,23 @@ void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state) // IF(SurfaceWindow(HeatTransSurfNum)%DividerArea > 0.0) THEN ! Window has dividers // DividerSolAbs = SurfaceWindow(HeatTransSurfNum)%DividerSolAbsorp - // IF(SurfaceWindow(HeatTransSurfNum)%DividerType == Suspended) THEN ! Suspended divider; account for inside glass + // IF(SurfaceWindow(HeatTransSurfNum)%DividerType == Suspended) THEN ! Suspended + // divider; account for inside glass // MatNumGl = Construct(ConstrNum)%LayerPoint(Construct(ConstrNum)%TotLayers) // TransGl = dataMaterial.Material(MatNumGl)%Trans // ReflGl = dataMaterial.Material(MatNumGl)%ReflectSolDiffBack // AbsGl = 1.0d0-TransGl-ReflGl // DividerSolRefl = 1.0d0-DividerSolAbs - // DividerSolAbs = AbsGl + TransGl*(DividerSolAbs + DividerSolRefl*AbsGl)/(1.0d0-DividerSolRefl*ReflGl) + // DividerSolAbs = AbsGl + TransGl*(DividerSolAbs + + // DividerSolRefl*AbsGl)/(1.0d0-DividerSolRefl*ReflGl) // END IF // Correct for interior shade transmittance // IF(ShadeFlag == IntShadeOn) THEN // MatNumSh = Construct(ConstrNumSh)%LayerPoint(Construct(ConstrNumSh)%TotLayers) // DividerSolAbs = DividerSolAbs * dataMaterial.Material(MatNumSh)%Trans // ELSE IF(ShadeFlag == WinShadingType::IntBlind) THEN - // DividerSolAbs = DividerSolAbs * InterpSlatAng(SurfaceWindow(HeatTransSurfNum)%SlatAngThisTS, & + // DividerSolAbs = DividerSolAbs * + // InterpSlatAng(SurfaceWindow(HeatTransSurfNum)%SlatAngThisTS, & // SurfaceWindow(HeatTransSurfNum)%MovableSlats,Blind(BlNum)%SolBackDiffDiffTrans) // END IF // Note that DividerQRadInAbs is initially calculated in InitSolarHeatGains @@ -12141,13 +12240,15 @@ void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state) // Check debug var for view factors here // ViewFactorTotal // Check debug vars for individual transmitting surfaces here - // WinDifSolarDistTotl = WinDifSolarDistAbsorbedTotl + WinDifSolarDistReflectedTotl + WinDifSolarDistTransmittedTotl; + // WinDifSolarDistTotl = WinDifSolarDistAbsorbedTotl + WinDifSolarDistReflectedTotl + + // WinDifSolarDistTransmittedTotl; // WinDifSolarTrans } // DifTransSurfNum = Zone(ZoneNum)%SurfaceFirst, Zone(ZoneNum)%SurfaceLast // Check debug vars for zone totals here - // ZoneDifSolarDistTotl = ZoneDifSolarDistAbsorbedTotl + ZoneDifSolarDistReflectedTotl + ZoneDifSolarDistTransmittedTotl; + // ZoneDifSolarDistTotl = ZoneDifSolarDistAbsorbedTotl + ZoneDifSolarDistReflectedTotl + + // ZoneDifSolarDistTransmittedTotl; // ZoneDifSolarTrans // ZoneDifSolarDistAbsorbedTotl // ZoneDifSolarDistReflectedTotl @@ -12156,11 +12257,11 @@ void CalcWinTransDifSolInitialDistribution(EnergyPlusData &state) } // ZoneNum = 1, NumOfZones } -void CalcInteriorWinTransDifSolInitialDistribution( - EnergyPlusData &state, - int const IntWinEnclosureNum, // Interior Window Enclosure index number - int const IntWinSurfNum, // Interior Window Surface number - Real64 const IntWinDifSolarTransW // Diffuse Solar transmitted through Interior Window IntWinSurfNum from adjacent enclosure [W] +void CalcInteriorWinTransDifSolInitialDistribution(EnergyPlusData &state, + int const IntWinEnclosureNum, // Interior Window Enclosure index number + int const IntWinSurfNum, // Interior Window Surface number + Real64 const IntWinDifSolarTransW // Diffuse Solar transmitted through Interior Window + // IntWinSurfNum from adjacent enclosure [W] ) { @@ -12216,20 +12317,24 @@ void CalcInteriorWinTransDifSolInitialDistribution( Real64 ViewFactor; // temp var for view factor Real64 ViewFactorTotal; // debug var for view factor total Real64 WinDifSolarTrans; // debug var for WinDifSolar() [W] - // Real64 WinDifSolarDistTotl; // debug var for window total distributed diffuse solar [W] - // Real64 WinDifSolarDistAbsorbedTotl( 0.0 ); // debug var for individual exterior window total + // Real64 WinDifSolarDistTotl; // debug var for window total distributed + // diffuse solar [W] Real64 WinDifSolarDistAbsorbedTotl( 0.0 ); // debug var + // for individual exterior window total // distributed // diffuse solar absorbed [W] - // Real64 WinDifSolarDistReflectedTotl( 0.0 ); // debug var for individual exterior window total distributed + // Real64 WinDifSolarDistReflectedTotl( 0.0 ); // debug var for individual exterior window total + // distributed // diffuse solar reflected [W] - // Real64 WinDifSolarDistTransmittedTotl( 0.0 ); // debug var for individual exterior window total distributed + // Real64 WinDifSolarDistTransmittedTotl( 0.0 ); // debug var for individual exterior window total + // distributed // diffuse solar transmitted [W] Real64 WinDifSolLayAbsW; // temp var for diffuse solar absorbed by individual glass layer [W] // Real64 ZoneDifSolarTrans( 0.0 ); // debug var for WinDifSolar() [W] // REAL(r64) :: ZoneDifSolarDistTotl ! debug var for zone total distributed diffuse solar [W] - // Real64 ZoneDifSolarDistAbsorbedTotl( 0.0 ); // debug var for zone total distributed diffuse solar absorbed [W] - // Real64 ZoneDifSolarDistReflectedTotl( 0.0 ); // debug var for zone total distributed diffuse solar reflected [W] - // Real64 ZoneDifSolarDistTransmittedTotl( 0.0 ); // debug var for zone total distributed diffuse solar transmitted [W] + // Real64 ZoneDifSolarDistAbsorbedTotl( 0.0 ); // debug var for zone total distributed diffuse solar + // absorbed [W] Real64 ZoneDifSolarDistReflectedTotl( 0.0 ); // debug var for zone total distributed + // diffuse solar reflected [W] Real64 ZoneDifSolarDistTransmittedTotl( 0.0 ); // debug var for zone + // total distributed diffuse solar transmitted [W] Real64 DifSolarAbsW; // temp var for diffuse solar absorbed by surface [W] Real64 DifSolarAbs; // temp var for diffuse solar absorbed by surface [W/m2] @@ -12269,8 +12374,8 @@ void CalcInteriorWinTransDifSolInitialDistribution( if (ViewFactor <= 0.0) continue; Real64 const SolarTrans_ViewFactor(IntWinDifSolarTransW * ViewFactor); - // Calculate diffuse solar from current interior window absorbed and reflected by current heat transfer surface - // And calculate transmitted diffuse solar to adjacent zones through interior windows + // Calculate diffuse solar from current interior window absorbed and reflected by current heat transfer + // surface And calculate transmitted diffuse solar to adjacent zones through interior windows int const ConstrNum = state.dataSurface->SurfActiveConstruction(HeatTransSurfNum); if (state.dataConstruction->Construct(ConstrNum).TransDiff <= 0.0) { // Interior Opaque Surface @@ -12281,7 +12386,8 @@ void CalcInteriorWinTransDifSolInitialDistribution( InsideDifReflectance = 1.0 - InsideDifAbsorptance; // Absorbed diffuse solar [W] = current window transmitted diffuse solar [W] - // * view factor from current (sending) window IntWinSurfNum to current (receiving) surface HeatTransSurfNum + // * view factor from current (sending) window IntWinSurfNum to current (receiving) surface + // HeatTransSurfNum // * current surface inside solar absorptance DifSolarAbsW = SolarTrans_ViewFactor * InsideDifAbsorptance; // [W] @@ -12293,11 +12399,13 @@ void CalcInteriorWinTransDifSolInitialDistribution( state.dataHeatBalSurf->SurfOpaqInitialDifSolInAbs(HeatTransSurfNum) += DifSolarAbs; // Reflected diffuse solar [W] = current window transmitted diffuse solar - // * view factor from current (sending) window IntWinSurfNum to current (receiving) surface HeatTransSurfNum + // * view factor from current (sending) window IntWinSurfNum to current (receiving) surface + // HeatTransSurfNum // * current window inside solar reflectance DifSolarReflW = SolarTrans_ViewFactor * InsideDifReflectance; - // Accumulate total reflected distributed diffuse solar for each zone for subsequent interreflection calcs + // Accumulate total reflected distributed diffuse solar for each zone for subsequent interreflection + // calcs InitialZoneDifSolReflW_zone += DifSolarReflW; // [W] // Accumulate Window and Zone total distributed diffuse solar to check for conservation of energy @@ -12326,10 +12434,12 @@ void CalcInteriorWinTransDifSolInitialDistribution( AbsInt = state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass); WinDifSolLayAbsW = SolarTrans_ViewFactor * state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass); - // Accumulate distributed diffuse solar absorbed [W] by overall window for transmittance calc below + // Accumulate distributed diffuse solar absorbed [W] by overall window for transmittance calc + // below DifSolarAbsW += WinDifSolLayAbsW; - // Accumulate diffuse solar absorbed from the inside by each window glass layer [W/m2] for heat balance calcs + // Accumulate diffuse solar absorbed from the inside by each window glass layer [W/m2] for + // heat balance calcs state.dataHeatBal->SurfWinInitialDifSolwinAbs(HeatTransSurfNum, IGlass) += (WinDifSolLayAbsW / state.dataSurface->Surface(HeatTransSurfNum).Area); } @@ -12341,11 +12451,13 @@ void CalcInteriorWinTransDifSolInitialDistribution( // I don't really care if this is a window or opaque surface since I am just // accumulating all reflected diffuse solar in a zone bucket for "interreflected" distribution // Reflected diffuse solar [W] = current window transmitted diffuse solar - // * view factor from current (sending) window IntWinSurfNum to current (receiving) surface HeatTransSurfNum + // * view factor from current (sending) window IntWinSurfNum to current (receiving) surface + // HeatTransSurfNum // * current window inside solar reflectance DifSolarReflW = SolarTrans_ViewFactor * state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack; - // Accumulate total reflected distributed diffuse solar for each zone for subsequent interreflection calcs + // Accumulate total reflected distributed diffuse solar for each zone for subsequent + // interreflection calcs InitialZoneDifSolReflW_zone += DifSolarReflW; // [W] // Accumulate Window and Zone total distributed diffuse solar to check for conservation of energy @@ -12353,12 +12465,13 @@ void CalcInteriorWinTransDifSolInitialDistribution( // WinDifSolarDistReflectedTotl += DifSolarReflW; // debug // ZoneDifSolarDistReflectedTotl += DifSolarReflW; // debug - // Calc transmitted Window and Zone total distributed diffuse solar to check for conservation of energy - // This is not very effective since it assigns whatever distributed diffuse solar has not been - // absorbed or reflected to transmitted. + // Calc transmitted Window and Zone total distributed diffuse solar to check for conservation of + // energy This is not very effective since it assigns whatever distributed diffuse solar has not + // been absorbed or reflected to transmitted. DifSolarTransW = SolarTrans_ViewFactor - DifSolarAbsW - DifSolarReflW; - // Accumulate transmitted Window and Zone total distributed diffuse solar to check for conservation of energy + // Accumulate transmitted Window and Zone total distributed diffuse solar to check for + // conservation of energy // WinDifSolarDistTransmittedTotl += DifSolarTransW; // debug [W] // ZoneDifSolarDistTransmittedTotl += DifSolarTransW; // debug [W] @@ -12397,10 +12510,12 @@ void CalcInteriorWinTransDifSolInitialDistribution( state.dataConstruction->Construct(ConstrNum).AbsDiffBack(IGlass), state.dataConstruction->Construct(ConstrNumSh).AbsDiffBack(IGlass)); - // Accumulate distributed diffuse solar absorbed [W] by overall window for transmittance calc below + // Accumulate distributed diffuse solar absorbed [W] by overall window for transmittance calc + // below DifSolarAbsW += WinDifSolLayAbsW; - // Accumulate diffuse solar absorbed from the inside by each window glass layer [W/m2] for heat balance calcs + // Accumulate diffuse solar absorbed from the inside by each window glass layer [W/m2] for + // heat balance calcs state.dataHeatBal->SurfWinInitialDifSolwinAbs(HeatTransSurfNum, IGlass) += (WinDifSolLayAbsW / state.dataSurface->Surface(HeatTransSurfNum).Area); } @@ -12413,19 +12528,21 @@ void CalcInteriorWinTransDifSolInitialDistribution( state.dataConstruction->Construct(ConstrNum).ReflectSolDiffBack, state.dataConstruction->Construct(ConstrNumSh).ReflectSolDiffBack); - // Accumulate total reflected distributed diffuse solar for each zone for subsequent interreflection calcs + // Accumulate total reflected distributed diffuse solar for each zone for subsequent + // interreflection calcs InitialZoneDifSolReflW_zone += DifSolarReflW; // [W] // Accumulate Window and Zone total distributed diffuse solar to check for conservation of energy // WinDifSolarDistReflectedTotl += DifSolarReflW; // debug // ZoneDifSolarDistReflectedTotl += DifSolarReflW; // debug - // Accumulate transmitted Window and Zone total distributed diffuse solar to check for conservation of energy - // This is not very effective since it assigns whatever distributed diffuse solar has not been - // absorbed or reflected to transmitted. + // Accumulate transmitted Window and Zone total distributed diffuse solar to check for + // conservation of energy This is not very effective since it assigns whatever distributed diffuse + // solar has not been absorbed or reflected to transmitted. DifSolarTransW = SolarTrans_ViewFactor - DifSolarAbsW - DifSolarReflW; // WinDifSolarDistTransmittedTotl += DifSolarTransW; // debug [W] - // ZoneDifSolarDistTransmittedTotl += DifSolarTransW; // debug [W] + // ZoneDifSolarDistTransmittedTotl += DifSolarTransW; // debug + //[W] // Accumulate transmitted diffuse solar for reporting state.dataHeatBalSurf->SurfWinInitialDifSolInTrans(HeatTransSurfNum) += @@ -12458,10 +12575,12 @@ void CalcInteriorWinTransDifSolInitialDistribution( WinDifSolLayAbsW = SolarTrans_ViewFactor * BlAbsDiffBk; } - // Accumulate distributed diffuse solar absorbed [W] by overall window for transmittance calc below + // Accumulate distributed diffuse solar absorbed [W] by overall window for transmittance calc + // below DifSolarAbsW += WinDifSolLayAbsW; - // Accumulate diffuse solar absorbed from the inside by each window glass layer [W/m2] for heat balance calcs + // Accumulate diffuse solar absorbed from the inside by each window glass layer [W/m2] for + // heat balance calcs state.dataHeatBal->SurfWinInitialDifSolwinAbs(HeatTransSurfNum, IGlass) += (WinDifSolLayAbsW / state.dataSurface->Surface(HeatTransSurfNum).Area); } @@ -12485,7 +12604,8 @@ void CalcInteriorWinTransDifSolInitialDistribution( } DifSolarReflW = SolarTrans_ViewFactor * InsideDifReflectance; - // Accumulate total reflected distributed diffuse solar for each zone for subsequent interreflection calcs + // Accumulate total reflected distributed diffuse solar for each zone for subsequent + // interreflection calcs InitialZoneDifSolReflW_zone += DifSolarReflW; // [W] // Accumulate Window and Zone total distributed diffuse solar to check for conservation of energy @@ -12518,16 +12638,17 @@ void CalcInteriorWinTransDifSolInitialDistribution( state.dataSurface->SurfWinInitialDifSolAbsByShade(HeatTransSurfNum) += (ShBlDifSolarAbsW / state.dataSurface->Surface(HeatTransSurfNum).Area); - // Accumulate distributed diffuse solar absorbed [W] by overall window for transmittance calc below + // Accumulate distributed diffuse solar absorbed [W] by overall window for transmittance calc + // below DifSolarAbsW += ShBlDifSolarAbsW; // Accumulate Window and Zone total distributed diffuse solar to check for conservation of energy // WinDifSolarDistAbsorbedTotl += ShBlDifSolarAbsW; // debug // ZoneDifSolarDistAbsorbedTotl += ShBlDifSolarAbsW; // debug - // Accumulate transmitted Window and Zone total distributed diffuse solar to check for conservation of energy - // This is not very effective since it assigns whatever distributed diffuse solar has not been - // absorbed or reflected to transmitted. + // Accumulate transmitted Window and Zone total distributed diffuse solar to check for + // conservation of energy This is not very effective since it assigns whatever distributed diffuse + // solar has not been absorbed or reflected to transmitted. DifSolarTransW = SolarTrans_ViewFactor - DifSolarAbsW - DifSolarReflW; // WinDifSolarDistTransmittedTotl += DifSolarTransW; // debug [W] // ZoneDifSolarDistTransmittedTotl += DifSolarTransW; // debug [W] @@ -12548,20 +12669,23 @@ void CalcInteriorWinTransDifSolInitialDistribution( // IF(SurfaceWindow(HeatTransSurfNum)%DividerArea > 0.0) THEN ! Window has dividers // DividerSolAbs = SurfaceWindow(HeatTransSurfNum)%DividerSolAbsorp - // IF(SurfaceWindow(HeatTransSurfNum)%DividerType == Suspended) THEN ! Suspended divider; account for inside glass + // IF(SurfaceWindow(HeatTransSurfNum)%DividerType == Suspended) THEN ! Suspended divider; + // account for inside glass // MatNumGl = Construct(ConstrNum)%LayerPoint(Construct(ConstrNum)%TotLayers) // TransGl = dataMaterial.Material(MatNumGl)%Trans // ReflGl = dataMaterial.Material(MatNumGl)%ReflectSolDiffBack // AbsGl = 1.0d0-TransGl-ReflGl // DividerSolRefl = 1.0d0-DividerSolAbs - // DividerSolAbs = AbsGl + TransGl*(DividerSolAbs + DividerSolRefl*AbsGl)/(1.0d0-DividerSolRefl*ReflGl) + // DividerSolAbs = AbsGl + TransGl*(DividerSolAbs + + // DividerSolRefl*AbsGl)/(1.0d0-DividerSolRefl*ReflGl) // END IF // Correct for interior shade transmittance // IF(ShadeFlag == IntShadeOn) THEN // MatNumSh = Construct(ConstrNumSh)%LayerPoint(Construct(ConstrNumSh)%TotLayers) // DividerSolAbs = DividerSolAbs * dataMaterial.Material(MatNumSh)%Trans // ELSE IF(ShadeFlag == WinShadingType::IntBlind) THEN - // DividerSolAbs = DividerSolAbs * InterpSlatAng(SurfaceWindow(HeatTransSurfNum)%SlatAngThisTS, & + // DividerSolAbs = DividerSolAbs * + // InterpSlatAng(SurfaceWindow(HeatTransSurfNum)%SlatAngThisTS, & // SurfaceWindow(HeatTransSurfNum)%MovableSlats,Blind(BlNum)%SolBackDiffDiffTrans) // END IF // Note that DividerQRadInAbs is initially calculated in InitSolarHeatGains @@ -12575,7 +12699,8 @@ void CalcInteriorWinTransDifSolInitialDistribution( // Check debug var for view factors here // ViewFactorTotal // Check debug vars for individual transmitting surfaces here - // WinDifSolarDistTotl = WinDifSolarDistAbsorbedTotl + WinDifSolarDistReflectedTotl + WinDifSolarDistTransmittedTotl; //Debug + // WinDifSolarDistTotl = WinDifSolarDistAbsorbedTotl + WinDifSolarDistReflectedTotl + + // WinDifSolarDistTransmittedTotl; //Debug // WinDifSolarTrans } @@ -12742,7 +12867,8 @@ void CalcComplexWindowOverlap(EnergyPlusData &state, } } - // Calculate overlap area times reflectance. This is necessary for complex fenestration daylighting calculations + // Calculate overlap area times reflectance. This is necessary for complex fenestration daylighting + // calculations TotAOverlap = 0.0; TotARhoVisOverlap = 0.0; for (KBkSurf = 1; KBkSurf <= Window.NBkSurf; ++KBkSurf) { // back surf loop diff --git a/src/EnergyPlus/SteamBaseboardRadiator.cc b/src/EnergyPlus/SteamBaseboardRadiator.cc index 4aecec3ea11..7cfd155dddb 100644 --- a/src/EnergyPlus/SteamBaseboardRadiator.cc +++ b/src/EnergyPlus/SteamBaseboardRadiator.cc @@ -992,7 +992,7 @@ namespace SteamBaseboardRadiator { if (state.dataGlobal->BeginTimeStepFlag && FirstHVACIteration) { int ZoneNum = state.dataSteamBaseboardRadiator->SteamBaseboard(BaseboardNum).ZonePtr; - state.dataSteamBaseboardRadiator->ZeroSourceSumHATsurf(ZoneNum) = SumHATsurf(state, ZoneNum); + state.dataSteamBaseboardRadiator->ZeroSourceSumHATsurf(ZoneNum) = state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state); state.dataSteamBaseboardRadiator->QBBSteamRadSrcAvg(BaseboardNum) = 0.0; state.dataSteamBaseboardRadiator->LastQBBSteamRadSrc(BaseboardNum) = 0.0; state.dataSteamBaseboardRadiator->LastSysTimeElapsed(BaseboardNum) = 0.0; @@ -1338,7 +1338,7 @@ namespace SteamBaseboardRadiator { // should include this. // Actual system load that the unit should meet - LoadMet = (SumHATsurf(state, ZoneNum) - state.dataSteamBaseboardRadiator->ZeroSourceSumHATsurf(ZoneNum)) + + LoadMet = (state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state) - state.dataSteamBaseboardRadiator->ZeroSourceSumHATsurf(ZoneNum)) + (SteamBBHeat * state.dataSteamBaseboardRadiator->SteamBaseboard(BaseboardNum).FracConvect) + (RadHeat * SteamBaseboardDesignDataObject.FracDistribPerson); state.dataSteamBaseboardRadiator->SteamBaseboard(BaseboardNum).SteamOutletEnthalpy = @@ -1556,72 +1556,6 @@ namespace SteamBaseboardRadiator { DataGlobalConstants::SecInHour; } - Real64 SumHATsurf(EnergyPlusData &state, int const ZoneNum) // Zone number - { - - // FUNCTION INFORMATION: - // AUTHOR Peter Graham Ellis - // DATE WRITTEN July 2003 - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS FUNCTION: - // This function calculates the zone sum of Hc*Area*Tsurf. It replaces the old SUMHAT. - // The SumHATsurf code below is also in the CalcZoneSums subroutine in ZoneTempPredictorCorrector - // and should be updated accordingly. - - // METHODOLOGY EMPLOYED: - // na - - // REFERENCES: - // na - - // Using/Aliasing - using namespace DataSurfaces; - using namespace DataHeatBalance; - using namespace DataHeatBalSurface; - - // Return value - Real64 SumHATsurf; - - // Locals - // FUNCTION ARGUMENT DEFINITIONS: - - // FUNCTION LOCAL VARIABLE DECLARATIONS: - int SurfNum; // Surface number - Real64 Area; // Effective surface area - - SumHATsurf = 0.0; - - for (SurfNum = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst; SurfNum <= state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast; ++SurfNum) { - Area = state.dataSurface->Surface(SurfNum).Area; - - if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Window) { - if (ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum))) { - // The area is the shade or blind area = the sum of the glazing area and the divider area (which is zero if no divider) - Area += state.dataSurface->SurfWinDividerArea(SurfNum); - } - - if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) { - // Window frame contribution - SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinFrameArea(SurfNum) * - (1.0 + state.dataSurface->SurfWinProjCorrFrIn(SurfNum)) * state.dataSurface->SurfWinFrameTempIn(SurfNum); - } - - if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0 && - !ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum))) { - // Window divider contribution (only from shade or blind for window with divider and interior shade or blind) - SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinDividerArea(SurfNum) * - (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) * state.dataSurface->SurfWinDividerTempIn(SurfNum); - } - } - - SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * Area * state.dataHeatBalSurf->SurfTempInTmp(SurfNum); - } - - return SumHATsurf; - } - void UpdateSteamBaseboardPlantConnection(EnergyPlusData &state, DataPlant::PlantEquipmentType BaseboardType, // type index diff --git a/src/EnergyPlus/SteamBaseboardRadiator.hh b/src/EnergyPlus/SteamBaseboardRadiator.hh index 0d38eb7e11f..9dd66e99e97 100644 --- a/src/EnergyPlus/SteamBaseboardRadiator.hh +++ b/src/EnergyPlus/SteamBaseboardRadiator.hh @@ -187,8 +187,6 @@ namespace SteamBaseboardRadiator { void ReportSteamBaseboard(EnergyPlusData &state, int const BaseboardNum); - Real64 SumHATsurf(EnergyPlusData &state, int const ZoneNum); // Zone number - void UpdateSteamBaseboardPlantConnection(EnergyPlusData &state, DataPlant::PlantEquipmentType BaseboardType, // type index std::string const &BaseboardName, // component name diff --git a/src/EnergyPlus/SurfaceGeometry.cc b/src/EnergyPlus/SurfaceGeometry.cc index a08647a6037..d4a6a87ac53 100644 --- a/src/EnergyPlus/SurfaceGeometry.cc +++ b/src/EnergyPlus/SurfaceGeometry.cc @@ -496,90 +496,87 @@ namespace SurfaceGeometry { for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { auto &thisZone = state.dataHeatBal->Zone(ZoneNum); - CeilCount = 0.0; - FloorCount = 0.0; - Count = 0; - AverageHeight = 0.0; - ZCeilAvg = 0.0; - ZFlrAvg = 0.0; - ZMax = -99999.0; - ZMin = 99999.0; - if (DetailedWWR) { - print(state.files.debug, "{},{:.2R},{:.2R}\n", thisZone.Name, thisZone.ExtGrossWallArea, thisZone.ExtWindowArea); - } - // Use AllSurfaceFirst which includes air boundaries - for (int SurfNum = thisZone.AllSurfaceFirst; SurfNum <= thisZone.AllSurfaceLast; ++SurfNum) { - auto &thisSurface = state.dataSurface->Surface(SurfNum); - - if (thisSurface.Class == SurfaceClass::Roof) { - // Use Average Z for surface, more important for roofs than floors... - ++CeilCount; - Z1 = minval(thisSurface.Vertex({1, thisSurface.Sides}), &Vector::z); - Z2 = maxval(thisSurface.Vertex({1, thisSurface.Sides}), &Vector::z); - // ZCeilAvg=ZCeilAvg+(Z1+Z2)/2.d0 - ZCeilAvg += ((Z1 + Z2) / 2.0) * (thisSurface.GrossArea / ZoneCeilingArea(ZoneNum)); - } - if (thisSurface.Class == SurfaceClass::Floor) { - // Use Average Z for surface, more important for roofs than floors... - ++FloorCount; - Z1 = minval(thisSurface.Vertex({1, thisSurface.Sides}), &Vector::z); - Z2 = maxval(thisSurface.Vertex({1, thisSurface.Sides}), &Vector::z); - // ZFlrAvg=ZFlrAvg+(Z1+Z2)/2.d0 - ZFlrAvg += ((Z1 + Z2) / 2.0) * (thisSurface.Area / thisZone.FloorArea); - } - if (thisSurface.Class == SurfaceClass::Wall) { - // Use Wall calculation in case no roof & floor in zone - ++Count; - if (Count == 1) { - ZMax = thisSurface.Vertex(1).z; - ZMin = ZMax; - } - ZMax = max(ZMax, maxval(thisSurface.Vertex({1, thisSurface.Sides}), &Vector::z)); - ZMin = min(ZMin, minval(thisSurface.Vertex({1, thisSurface.Sides}), &Vector::z)); - } - } - if (CeilCount > 0.0 && FloorCount > 0.0) { - AverageHeight = ZCeilAvg - ZFlrAvg; - } else { - AverageHeight = (ZMax - ZMin); - } - if (AverageHeight <= 0.0) { - AverageHeight = (ZMax - ZMin); - } - - if (thisZone.CeilingHeight > 0.0) { - ZoneCeilingHeightEntered(ZoneNum) = true; - if (AverageHeight > 0.0) { - if (std::abs(AverageHeight - thisZone.CeilingHeight) / thisZone.CeilingHeight > 0.05) { - if (ErrCount == 1 && !state.dataGlobal->DisplayExtraWarnings) { - ShowWarningError(state, - std::string{RoutineName} + - "Entered Ceiling Height for some zone(s) significantly different from calculated Ceiling Height"); - ShowContinueError(state, - "...use Output:Diagnostics,DisplayExtraWarnings; to show more details on each max iteration exceeded."); - } - if (state.dataGlobal->DisplayExtraWarnings) { - ShowWarningError(state, - std::string{RoutineName} + "Entered Ceiling Height for Zone=\"" + thisZone.Name + - "\" significantly different from calculated Ceiling Height"); - static constexpr std::string_view ValFmt("{:.2F}"); - String1 = format(ValFmt, thisZone.CeilingHeight); - String2 = format(ValFmt, AverageHeight); - ShowContinueError(state, - std::string{RoutineName} + "Entered Ceiling Height=" + String1 + - ", Calculated Ceiling Height=" + String2 + ", entered height will be used in calculations."); + for (int spaceNum : thisZone.spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + CeilCount = 0.0; + FloorCount = 0.0; + Count = 0; + AverageHeight = 0.0; + ZCeilAvg = 0.0; + ZFlrAvg = 0.0; + ZMax = -99999.0; + ZMin = 99999.0; + if (DetailedWWR) { + print(state.files.debug, "{},{:.2R},{:.2R}\n", thisZone.Name, thisZone.ExtGrossWallArea, thisZone.ExtWindowArea); + } + // Use AllSurfaceFirst which includes air boundaries + for (int SurfNum = thisSpace.AllSurfaceFirst; SurfNum <= thisSpace.AllSurfaceLast; ++SurfNum) { + auto &thisSurface = state.dataSurface->Surface(SurfNum); + + if (thisSurface.Class == SurfaceClass::Roof) { + // Use Average Z for surface, more important for roofs than floors... + ++CeilCount; + Z1 = minval(thisSurface.Vertex({1, thisSurface.Sides}), &Vector::z); + Z2 = maxval(thisSurface.Vertex({1, thisSurface.Sides}), &Vector::z); + // ZCeilAvg=ZCeilAvg+(Z1+Z2)/2.d0 + ZCeilAvg += ((Z1 + Z2) / 2.0) * (thisSurface.GrossArea / ZoneCeilingArea(ZoneNum)); + } + if (thisSurface.Class == SurfaceClass::Floor) { + // Use Average Z for surface, more important for roofs than floors... + ++FloorCount; + Z1 = minval(thisSurface.Vertex({1, thisSurface.Sides}), &Vector::z); + Z2 = maxval(thisSurface.Vertex({1, thisSurface.Sides}), &Vector::z); + // ZFlrAvg=ZFlrAvg+(Z1+Z2)/2.d0 + ZFlrAvg += ((Z1 + Z2) / 2.0) * (thisSurface.Area / thisZone.FloorArea); + } + if (thisSurface.Class == SurfaceClass::Wall) { + // Use Wall calculation in case no roof & floor in zone + ++Count; + if (Count == 1) { + ZMax = thisSurface.Vertex(1).z; + ZMin = ZMax; } + ZMax = max(ZMax, maxval(thisSurface.Vertex({1, thisSurface.Sides}), &Vector::z)); + ZMin = min(ZMin, minval(thisSurface.Vertex({1, thisSurface.Sides}), &Vector::z)); } } - } - if ((thisZone.CeilingHeight <= 0.0) && (AverageHeight > 0.0)) thisZone.CeilingHeight = AverageHeight; - // For now - set space ceiling height to zone ceiling height, if not entered - for (int spaceNum : thisZone.spaceIndexes) { - auto &thisSpace = state.dataHeatBal->space(spaceNum); - // don't touch if already user-specified - if (thisSpace.CeilingHeight == 0.0) { - thisSpace.CeilingHeight = thisZone.CeilingHeight; + if (CeilCount > 0.0 && FloorCount > 0.0) { + AverageHeight = ZCeilAvg - ZFlrAvg; + } else { + AverageHeight = (ZMax - ZMin); + } + if (AverageHeight <= 0.0) { + AverageHeight = (ZMax - ZMin); } + + if (thisZone.CeilingHeight > 0.0) { + ZoneCeilingHeightEntered(ZoneNum) = true; + if (AverageHeight > 0.0) { + if (std::abs(AverageHeight - thisZone.CeilingHeight) / thisZone.CeilingHeight > 0.05) { + if (ErrCount == 1 && !state.dataGlobal->DisplayExtraWarnings) { + ShowWarningError( + state, + std::string{RoutineName} + + "Entered Ceiling Height for some zone(s) significantly different from calculated Ceiling Height"); + ShowContinueError( + state, "...use Output:Diagnostics,DisplayExtraWarnings; to show more details on each max iteration exceeded."); + } + if (state.dataGlobal->DisplayExtraWarnings) { + ShowWarningError(state, + std::string{RoutineName} + "Entered Ceiling Height for Zone=\"" + thisZone.Name + + "\" significantly different from calculated Ceiling Height"); + static constexpr std::string_view ValFmt("{:.2F}"); + String1 = format(ValFmt, thisZone.CeilingHeight); + String2 = format(ValFmt, AverageHeight); + ShowContinueError(state, + std::string{RoutineName} + "Entered Ceiling Height=" + String1 + + ", Calculated Ceiling Height=" + String2 + ", entered height will be used in calculations."); + } + } + } + } + if ((thisZone.CeilingHeight <= 0.0) && (AverageHeight > 0.0)) thisZone.CeilingHeight = AverageHeight; + // Need to add check here - don't touch if already user-specified } } @@ -600,24 +597,28 @@ namespace SurfaceGeometry { thisZone.MinimumZ = state.dataSurface->Surface(thisZone.AllSurfaceFirst).Vertex(1).z; thisZone.MaximumZ = state.dataSurface->Surface(thisZone.AllSurfaceFirst).Vertex(1).z; } - for (int SurfNum = thisZone.AllSurfaceFirst; SurfNum <= thisZone.HTSurfaceLast; ++SurfNum) { - auto &thisSurface = state.dataSurface->Surface(SurfNum); - if (thisSurface.Class == SurfaceClass::IntMass) continue; - nonInternalMassSurfacesPresent = true; - if (thisSurface.Class == SurfaceClass::Wall || (thisSurface.Class == SurfaceClass::Roof) || - (thisSurface.Class == SurfaceClass::Floor)) { - - thisZone.Centroid.x += thisSurface.Centroid.x * thisSurface.GrossArea; - thisZone.Centroid.y += thisSurface.Centroid.y * thisSurface.GrossArea; - thisZone.Centroid.z += thisSurface.Centroid.z * thisSurface.GrossArea; - TotSurfArea += thisSurface.GrossArea; - } - thisZone.MinimumX = min(thisZone.MinimumX, minval(thisSurface.Vertex({1, thisSurface.Sides}), &Vector::x)); - thisZone.MaximumX = max(thisZone.MaximumX, maxval(thisSurface.Vertex({1, thisSurface.Sides}), &Vector::x)); - thisZone.MinimumY = min(thisZone.MinimumY, minval(thisSurface.Vertex({1, thisSurface.Sides}), &Vector::y)); - thisZone.MaximumY = max(thisZone.MaximumY, maxval(thisSurface.Vertex({1, thisSurface.Sides}), &Vector::y)); - thisZone.MinimumZ = min(thisZone.MinimumZ, minval(thisSurface.Vertex({1, thisSurface.Sides}), &Vector::z)); - thisZone.MaximumZ = max(thisZone.MaximumZ, maxval(thisSurface.Vertex({1, thisSurface.Sides}), &Vector::z)); + for (int spaceNum : thisZone.spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + + for (int SurfNum = thisSpace.AllSurfaceFirst; SurfNum <= thisSpace.AllSurfaceLast; ++SurfNum) { + auto &thisSurface = state.dataSurface->Surface(SurfNum); + if (thisSurface.Class == SurfaceClass::IntMass) continue; + nonInternalMassSurfacesPresent = true; + if (thisSurface.Class == SurfaceClass::Wall || (thisSurface.Class == SurfaceClass::Roof) || + (thisSurface.Class == SurfaceClass::Floor)) { + + thisZone.Centroid.x += thisSurface.Centroid.x * thisSurface.GrossArea; + thisZone.Centroid.y += thisSurface.Centroid.y * thisSurface.GrossArea; + thisZone.Centroid.z += thisSurface.Centroid.z * thisSurface.GrossArea; + TotSurfArea += thisSurface.GrossArea; + } + thisZone.MinimumX = min(thisZone.MinimumX, minval(thisSurface.Vertex({1, thisSurface.Sides}), &Vector::x)); + thisZone.MaximumX = max(thisZone.MaximumX, maxval(thisSurface.Vertex({1, thisSurface.Sides}), &Vector::x)); + thisZone.MinimumY = min(thisZone.MinimumY, minval(thisSurface.Vertex({1, thisSurface.Sides}), &Vector::y)); + thisZone.MaximumY = max(thisZone.MaximumY, maxval(thisSurface.Vertex({1, thisSurface.Sides}), &Vector::y)); + thisZone.MinimumZ = min(thisZone.MinimumZ, minval(thisSurface.Vertex({1, thisSurface.Sides}), &Vector::z)); + thisZone.MaximumZ = max(thisZone.MaximumZ, maxval(thisSurface.Vertex({1, thisSurface.Sides}), &Vector::z)); + } } if (TotSurfArea > 0.0) { thisZone.Centroid.x /= TotSurfArea; @@ -727,7 +728,8 @@ namespace SurfaceGeometry { "{m},Centroid X-Coordinate {m},Centroid Y-Coordinate {m},Centroid Z-Coordinate {m},Type,Zone Multiplier,Zone List " "Multiplier,Minimum X {m},Maximum X {m},Minimum Y {m},Maximum Y {m},Minimum Z {m},Maximum Z {m},Ceiling Height {m},Volume " "{m3},Zone Inside Convection Algorithm {Simple-Detailed-CeilingDiffuser-TrombeWall},Zone Outside Convection Algorithm " - "{Simple-Detailed-Tarp-MoWitt-DOE-2-BLAST}, Floor Area {m2},Exterior Gross Wall Area {m2},Exterior Net Wall Area {m2},Exterior Window " + "{Simple-Detailed-Tarp-MoWitt-DOE-2-BLAST}, Floor Area {m2},Exterior Gross Wall Area {m2},Exterior Net Wall Area {m2},Exterior " + "Window " "Area {m2}, Number of Surfaces, Number of SubSurfaces, Number of Shading SubSurfaces, Part of Total Building Area"); print(state.files.eio, "{}\n", Format_721); @@ -1030,15 +1032,15 @@ namespace SurfaceGeometry { // The order of surfaces does not matter and the surfaces are resorted into // the hierarchical order: // All Shading Surfaces - // Airwalls for zone x1 - // Base Surfaces for zone x1 - // Opaque Subsurfaces for zone x1 - // Window Subsurfaces for zone x1 - // TDD Dome Surfaces for zone x1 - // Airwalls for zone x2 - // Base Surfaces for zone x2 + // Airwalls for space x1 + // Base Surfaces for space x1 + // Opaque Subsurfaces for space x1 + // Window Subsurfaces for space x1 + // TDD Dome Surfaces for space x1 + // Airwalls for space x2 + // Base Surfaces for space x2 // etc - // Pointers are set in the zones (AllSurfaceFirst/Last, HTSurfaceFirst/Last, OpaqOrIntMassSurfaceFirst/Last, WindowSurfaceFirst/Last, + // Pointers are set in the spaces (AllSurfaceFirst/Last, HTSurfaceFirst/Last, OpaqOrIntMassSurfaceFirst/Last, WindowSurfaceFirst/Last, // OpaqOrWinSurfaceFirst/Last, TDDDomeFirst/Last) // REFERENCES: @@ -1152,9 +1154,6 @@ namespace SurfaceGeometry { int TotOverhangsProjection; int TotFins; int TotFinsProjection; - int OpaqueHTSurfs; // Number of floors, walls and roofs in a zone - int OpaqueHTSurfsWithWin; // Number of floors, walls and roofs with windows in a zone - int InternalMassSurfs; // Number of internal mass surfaces in a zone bool RelWarning(false); int ConstrNumSh; // Shaded construction number for a window int LayNumOutside; // Outside material numbers for a shaded construction @@ -1535,13 +1534,13 @@ namespace SurfaceGeometry { } // ...end of the Surface DO loop for finding BaseSurf //********************************************************************************** - // The surfaces need to be hierarchical by zone. Input is allowed to be in any order. In + // The surfaces need to be hierarchical by space. Input is allowed to be in any order. In // this section the surfaces are reordered into: // All shadowing surfaces (if mirrored, Mir- surface follows immediately after original) // Shading:Site // Shading:Building - // Shading:Zone (and variants) - // For each zone: + // Shading:space (and variants) + // For each space: // Walls // Floors // Roofs/Ceilings @@ -1571,6 +1570,8 @@ namespace SurfaceGeometry { SurfaceTmpClassMoved.dimension(state.dataSurface->TotSurfaces, false); state.dataSurface->AllSurfaceListReportOrder.reserve(state.dataSurface->TotSurfaces); + CreateMissingSpaces(state, state.dataSurfaceGeometry->SurfaceTmp); + // Old SurfNum to New SurfNum // Old = order in state.dataSurfaceGeometry->SurfaceTmp // New = order in state.dataSurface->Surface @@ -1596,147 +1597,147 @@ namespace SurfaceGeometry { // For each zone for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { - // Group air boundary surfaces first within each zone - for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) { - if (SurfaceTmpClassMoved(SurfNum)) continue; - if (state.dataSurfaceGeometry->SurfaceTmp(SurfNum).Zone != ZoneNum) continue; - int constNum = state.dataSurfaceGeometry->SurfaceTmp(SurfNum).Construction; - if (constNum == 0) continue; - if (!state.dataConstruction->Construct(constNum).TypeIsAirBoundary) continue; - - // An air boundary surface - state.dataSurfaceGeometry->SurfaceTmp(SurfNum).IsAirBoundarySurf = true; - ++MovedSurfs; - state.dataSurface->Surface(MovedSurfs) = state.dataSurfaceGeometry->SurfaceTmp(SurfNum); - // If base Surface Type (Wall, Floor, Roof/Ceiling) - if ((state.dataSurfaceGeometry->SurfaceTmp(SurfNum).Class == state.dataSurfaceGeometry->BaseSurfIDs(1)) || - (state.dataSurfaceGeometry->SurfaceTmp(SurfNum).Class == state.dataSurfaceGeometry->BaseSurfIDs(2)) || - (state.dataSurfaceGeometry->SurfaceTmp(SurfNum).Class == state.dataSurfaceGeometry->BaseSurfIDs(3))) { - // Store list of moved surface numbers in reporting order. We use the old position, we'll reconcile later - // We don't do it for Air Door/Air Windows yet, we want them listed below each base surf they belong to - state.dataSurface->AllSurfaceListReportOrder.push_back(SurfNum); + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + // Group air boundary surfaces first within each space + for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) { + if (SurfaceTmpClassMoved(SurfNum)) continue; + if (state.dataSurfaceGeometry->SurfaceTmp(SurfNum).spaceNum != spaceNum) continue; + int constNum = state.dataSurfaceGeometry->SurfaceTmp(SurfNum).Construction; + if (constNum == 0) continue; + if (!state.dataConstruction->Construct(constNum).TypeIsAirBoundary) continue; + + // An air boundary surface + state.dataSurfaceGeometry->SurfaceTmp(SurfNum).IsAirBoundarySurf = true; + ++MovedSurfs; + state.dataSurface->Surface(MovedSurfs) = state.dataSurfaceGeometry->SurfaceTmp(SurfNum); + // If base Surface Type (Wall, Floor, Roof/Ceiling) + if ((state.dataSurfaceGeometry->SurfaceTmp(SurfNum).Class == state.dataSurfaceGeometry->BaseSurfIDs(1)) || + (state.dataSurfaceGeometry->SurfaceTmp(SurfNum).Class == state.dataSurfaceGeometry->BaseSurfIDs(2)) || + (state.dataSurfaceGeometry->SurfaceTmp(SurfNum).Class == state.dataSurfaceGeometry->BaseSurfIDs(3))) { + // Store list of moved surface numbers in reporting order. We use the old position, we'll reconcile later + // We don't do it for Air Door/Air Windows yet, we want them listed below each base surf they belong to + state.dataSurface->AllSurfaceListReportOrder.push_back(SurfNum); + } + oldToNewSurfNums(SurfNum) = MovedSurfs; + SurfaceTmpClassMoved(SurfNum) = true; //'Moved' } - oldToNewSurfNums(SurfNum) = MovedSurfs; - SurfaceTmpClassMoved(SurfNum) = true; //'Moved' - } - // For each Base Surface Type (Wall, Floor, Roof/Ceiling) - put these first + // For each Base Surface Type (Wall, Floor, Roof/Ceiling) - put these first - for (int Loop = 1; Loop <= 3; ++Loop) { + for (int Loop = 1; Loop <= 3; ++Loop) { - for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) { + for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) { - if (SurfaceTmpClassMoved(SurfNum)) continue; - if (state.dataSurfaceGeometry->SurfaceTmp(SurfNum).Zone == 0) continue; + if (SurfaceTmpClassMoved(SurfNum)) continue; + if (state.dataSurfaceGeometry->SurfaceTmp(SurfNum).Zone == 0) continue; - if (!UtilityRoutines::SameString(state.dataSurfaceGeometry->SurfaceTmp(SurfNum).ZoneName, state.dataHeatBal->Zone(ZoneNum).Name)) - continue; - if (state.dataSurfaceGeometry->SurfaceTmp(SurfNum).Class != state.dataSurfaceGeometry->BaseSurfIDs(Loop)) continue; + if (state.dataSurfaceGeometry->SurfaceTmp(SurfNum).spaceNum != spaceNum) continue; + if (state.dataSurfaceGeometry->SurfaceTmp(SurfNum).Class != state.dataSurfaceGeometry->BaseSurfIDs(Loop)) continue; + ++MovedSurfs; + state.dataSurface->Surface(MovedSurfs) = state.dataSurfaceGeometry->SurfaceTmp(SurfNum); + oldToNewSurfNums(SurfNum) = MovedSurfs; + SurfaceTmpClassMoved(SurfNum) = true; // 'Moved' + // Store list of moved surface numbers in order reporting order (subsurfaces follow their base surface) + state.dataSurface->AllSurfaceListReportOrder.push_back(SurfNum); + + // Find all subsurfaces to this surface - just to update Report them in order + for (int SubSurfNum = 1; SubSurfNum <= state.dataSurface->TotSurfaces; ++SubSurfNum) { + // Gotta avoid pushing myself again! + if (SubSurfNum == SurfNum) continue; + // We don't check if already moved, because we didn't add them to AllSurfaceListReportOrder above! + if (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).Zone == 0) continue; + if (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).BaseSurf != SurfNum) continue; + // Add original sub-surface numbers as placeholders in surface list for reporting + state.dataSurface->AllSurfaceListReportOrder.push_back(SubSurfNum); + } + } + } + + // Internal mass goes next + for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) { + + if (SurfaceTmpClassMoved(SurfNum)) continue; + if (state.dataSurfaceGeometry->SurfaceTmp(SurfNum).spaceNum != spaceNum) continue; + if (state.dataSurfaceGeometry->SurfaceTmp(SurfNum).Class != SurfaceClass::IntMass) continue; ++MovedSurfs; state.dataSurface->Surface(MovedSurfs) = state.dataSurfaceGeometry->SurfaceTmp(SurfNum); oldToNewSurfNums(SurfNum) = MovedSurfs; SurfaceTmpClassMoved(SurfNum) = true; // 'Moved' - // Store list of moved surface numbers in order reporting order (subsurfaces follow their base surface) + // Store list of moved surface numbers in reporting order state.dataSurface->AllSurfaceListReportOrder.push_back(SurfNum); - - // Find all subsurfaces to this surface - just to update Report them in order - for (int SubSurfNum = 1; SubSurfNum <= state.dataSurface->TotSurfaces; ++SubSurfNum) { - // Gotta avoid pushing myself again! - if (SubSurfNum == SurfNum) continue; - // We don't check if already moved, because we didn't add them to AllSurfaceListReportOrder above! - if (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).Zone == 0) continue; - if (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).BaseSurf != SurfNum) continue; - // Add original sub-surface numbers as placeholders in surface list for reporting - state.dataSurface->AllSurfaceListReportOrder.push_back(SubSurfNum); - } } - } - - // Internal mass goes next - for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) { - if (SurfaceTmpClassMoved(SurfNum)) continue; - if (!UtilityRoutines::SameString(state.dataSurfaceGeometry->SurfaceTmp(SurfNum).ZoneName, state.dataHeatBal->Zone(ZoneNum).Name)) - continue; - if (state.dataSurfaceGeometry->SurfaceTmp(SurfNum).Class != SurfaceClass::IntMass) continue; - ++MovedSurfs; - state.dataSurface->Surface(MovedSurfs) = state.dataSurfaceGeometry->SurfaceTmp(SurfNum); - oldToNewSurfNums(SurfNum) = MovedSurfs; - SurfaceTmpClassMoved(SurfNum) = true; // 'Moved' - // Store list of moved surface numbers in reporting order - state.dataSurface->AllSurfaceListReportOrder.push_back(SurfNum); - } - - // Opaque door goes next - for (int SubSurfNum = 1; SubSurfNum <= state.dataSurface->TotSurfaces; ++SubSurfNum) { + // Opaque door goes next + for (int SubSurfNum = 1; SubSurfNum <= state.dataSurface->TotSurfaces; ++SubSurfNum) { - if (SurfaceTmpClassMoved(SubSurfNum)) continue; - if (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).Zone != ZoneNum) continue; - if (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).Class != SurfaceClass::Door) continue; + if (SurfaceTmpClassMoved(SubSurfNum)) continue; + if (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).spaceNum != spaceNum) continue; + if (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).Class != SurfaceClass::Door) continue; - ++MovedSurfs; - state.dataSurface->Surface(MovedSurfs) = state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum); - oldToNewSurfNums(SubSurfNum) = MovedSurfs; - SurfaceTmpClassMoved(SubSurfNum) = true; // 'Moved' - } + ++MovedSurfs; + state.dataSurface->Surface(MovedSurfs) = state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum); + oldToNewSurfNums(SubSurfNum) = MovedSurfs; + SurfaceTmpClassMoved(SubSurfNum) = true; // 'Moved' + } - // The exterior window subsurfaces (includes SurfaceClass::Window and SurfaceClass::GlassDoor) goes next - for (int SubSurfNum = 1; SubSurfNum <= state.dataSurface->TotSurfaces; ++SubSurfNum) { + // The exterior window subsurfaces (includes SurfaceClass::Window and SurfaceClass::GlassDoor) goes next + for (int SubSurfNum = 1; SubSurfNum <= state.dataSurface->TotSurfaces; ++SubSurfNum) { - if (SurfaceTmpClassMoved(SubSurfNum)) continue; - if (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).Zone != ZoneNum) continue; - if (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).ExtBoundCond > 0) continue; // Exterior window - if ((state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).Class != SurfaceClass::Window) && - (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).Class != SurfaceClass::GlassDoor)) - continue; + if (SurfaceTmpClassMoved(SubSurfNum)) continue; + if (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).spaceNum != spaceNum) continue; + if (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).ExtBoundCond > 0) continue; // Exterior window + if ((state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).Class != SurfaceClass::Window) && + (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).Class != SurfaceClass::GlassDoor)) + continue; - ++MovedSurfs; - state.dataSurface->Surface(MovedSurfs) = state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum); - oldToNewSurfNums(SubSurfNum) = MovedSurfs; - SurfaceTmpClassMoved(SubSurfNum) = true; // 'Moved' - } + ++MovedSurfs; + state.dataSurface->Surface(MovedSurfs) = state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum); + oldToNewSurfNums(SubSurfNum) = MovedSurfs; + SurfaceTmpClassMoved(SubSurfNum) = true; // 'Moved' + } - // The interior window subsurfaces (includes SurfaceClass::Window and SurfaceClass::GlassDoor) goes next - for (int SubSurfNum = 1; SubSurfNum <= state.dataSurface->TotSurfaces; ++SubSurfNum) { + // The interior window subsurfaces (includes SurfaceClass::Window and SurfaceClass::GlassDoor) goes next + for (int SubSurfNum = 1; SubSurfNum <= state.dataSurface->TotSurfaces; ++SubSurfNum) { - if (SurfaceTmpClassMoved(SubSurfNum)) continue; - if (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).Zone != ZoneNum) continue; - if (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).ExtBoundCond <= 0) continue; - if ((state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).Class != SurfaceClass::Window) && - (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).Class != SurfaceClass::GlassDoor)) - continue; + if (SurfaceTmpClassMoved(SubSurfNum)) continue; + if (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).spaceNum != spaceNum) continue; + if (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).ExtBoundCond <= 0) continue; + if ((state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).Class != SurfaceClass::Window) && + (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).Class != SurfaceClass::GlassDoor)) + continue; - ++MovedSurfs; - state.dataSurface->Surface(MovedSurfs) = state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum); - oldToNewSurfNums(SubSurfNum) = MovedSurfs; - SurfaceTmpClassMoved(SubSurfNum) = true; // 'Moved' - } + ++MovedSurfs; + state.dataSurface->Surface(MovedSurfs) = state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum); + oldToNewSurfNums(SubSurfNum) = MovedSurfs; + SurfaceTmpClassMoved(SubSurfNum) = true; // 'Moved' + } - // The SurfaceClass::TDD_Diffuser (OriginalClass = Window) goes next - for (int SubSurfNum = 1; SubSurfNum <= state.dataSurface->TotSurfaces; ++SubSurfNum) { + // The SurfaceClass::TDD_Diffuser (OriginalClass = Window) goes next + for (int SubSurfNum = 1; SubSurfNum <= state.dataSurface->TotSurfaces; ++SubSurfNum) { - if (SurfaceTmpClassMoved(SubSurfNum)) continue; - if (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).Zone != ZoneNum) continue; - if (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).Class != SurfaceClass::TDD_Diffuser) continue; + if (SurfaceTmpClassMoved(SubSurfNum)) continue; + if (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).spaceNum != spaceNum) continue; + if (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).Class != SurfaceClass::TDD_Diffuser) continue; - ++MovedSurfs; - state.dataSurface->Surface(MovedSurfs) = state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum); - oldToNewSurfNums(SubSurfNum) = MovedSurfs; - SurfaceTmpClassMoved(SubSurfNum) = true; // 'Moved' - } + ++MovedSurfs; + state.dataSurface->Surface(MovedSurfs) = state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum); + oldToNewSurfNums(SubSurfNum) = MovedSurfs; + SurfaceTmpClassMoved(SubSurfNum) = true; // 'Moved' + } - // Last but not least, SurfaceClass::TDD_Dome - for (int SubSurfNum = 1; SubSurfNum <= state.dataSurface->TotSurfaces; ++SubSurfNum) { + // Last but not least, SurfaceClass::TDD_Dome + for (int SubSurfNum = 1; SubSurfNum <= state.dataSurface->TotSurfaces; ++SubSurfNum) { - if (SurfaceTmpClassMoved(SubSurfNum)) continue; - if (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).Zone != ZoneNum) continue; - if (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).Class != SurfaceClass::TDD_Dome) continue; + if (SurfaceTmpClassMoved(SubSurfNum)) continue; + if (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).spaceNum != spaceNum) continue; + if (state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum).Class != SurfaceClass::TDD_Dome) continue; - ++MovedSurfs; - state.dataSurface->Surface(MovedSurfs) = state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum); - oldToNewSurfNums(SubSurfNum) = MovedSurfs; - SurfaceTmpClassMoved(SubSurfNum) = true; // 'Moved' + ++MovedSurfs; + state.dataSurface->Surface(MovedSurfs) = state.dataSurfaceGeometry->SurfaceTmp(SubSurfNum); + oldToNewSurfNums(SubSurfNum) = MovedSurfs; + SurfaceTmpClassMoved(SubSurfNum) = true; // 'Moved' + } } } @@ -1795,7 +1796,7 @@ namespace SurfaceGeometry { state.dataSurfaceGeometry->SurfaceTmp.deallocate(); // DeAllocate the Temp Surface derived type - CreateMissingSpaces(state, ErrorsFound); + createSpaceSurfaceLists(state, ErrorsFound); // For each Base Surface Type (Wall, Floor, Roof) @@ -1918,9 +1919,9 @@ namespace SurfaceGeometry { " does not have the same materials in the reverse order as the construction " + state.dataConstruction->Construct(ConstrNumFound).Name + " of adjacent surface " + state.dataSurface->Surface(Found).Name); - ShowContinueError( - state, - "or the properties of the reversed layers are not correct due to differing layer front and back side values"); + ShowContinueError(state, + "or the properties of the reversed layers are not correct due to differing layer front and " + "back side values"); if (!state.dataConstruction->Construct(ConstrNum).ReverseConstructionLayersOrderWarning || !state.dataConstruction->Construct(ConstrNumFound).ReverseConstructionLayersOrderWarning) { ShowContinueError(state, "...this problem for this pair will not be reported again."); @@ -1935,9 +1936,9 @@ namespace SurfaceGeometry { " does not have the same materials in the reverse order as the construction " + state.dataConstruction->Construct(ConstrNumFound).Name + " of adjacent surface " + state.dataSurface->Surface(Found).Name); - ShowContinueError( - state, - "or the properties of the reversed layers are not correct due to differing layer front and back side values"); + ShowContinueError(state, + "or the properties of the reversed layers are not correct due to differing layer front and " + "back side values"); ShowContinueError( state, format("...but Nominal U values are similar, diff=[{:.4R}] ... simulation proceeds.", @@ -1968,18 +1969,16 @@ namespace SurfaceGeometry { state.dataSurface->Surface(Found).Area * MultFound) > 0.02) { // 2% difference in areas ++ErrCount4; if (ErrCount4 == 1 && !state.dataGlobal->DisplayExtraWarnings) { - ShowWarningError( - state, - std::string{RoutineName} + - "InterZone Surface Areas do not match as expected and might not satisfy conservation of energy:"); + ShowWarningError(state, + std::string{RoutineName} + "InterZone Surface Areas do not match as expected and " + "might not satisfy conservation of energy:"); ShowContinueError( state, "...use Output:Diagnostics,DisplayExtraWarnings; to show more details on individual mismatches."); } if (state.dataGlobal->DisplayExtraWarnings) { - ShowWarningError( - state, - std::string{RoutineName} + - "InterZone Surface Areas do not match as expected and might not satisfy conservation of energy:"); + ShowWarningError(state, + std::string{RoutineName} + "InterZone Surface Areas do not match as expected and " + "might not satisfy conservation of energy:"); if (MultFound == 1 && MultSurfNum == 1) { ShowContinueError(state, @@ -2283,77 +2282,109 @@ namespace SurfaceGeometry { //********************************************************************************** // Set up Zone Surface Pointers for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { - for (int SurfNum = 1; SurfNum <= MovedSurfs; ++SurfNum) { // TotSurfaces - if (state.dataSurface->Surface(SurfNum).Zone == ZoneNum) { - if (state.dataHeatBal->Zone(ZoneNum).AllSurfaceFirst == 0) { - state.dataHeatBal->Zone(ZoneNum).AllSurfaceFirst = SurfNum; - } - if (state.dataSurface->Surface(SurfNum).IsAirBoundarySurf) { - state.dataSurface->Surface(SurfNum).HeatTransSurf = false; - continue; - } - if (state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst == 0) { - state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst = SurfNum; - // Non window surfaces are grouped next within each zone - state.dataHeatBal->Zone(ZoneNum).OpaqOrIntMassSurfaceFirst = SurfNum; - } - if ((state.dataHeatBal->Zone(ZoneNum).WindowSurfaceFirst == 0) && - ((state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window) || - (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::GlassDoor) || - (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::TDD_Diffuser))) { - // Window surfaces are grouped last within each zone - state.dataHeatBal->Zone(ZoneNum).WindowSurfaceFirst = SurfNum; - state.dataHeatBal->Zone(ZoneNum).OpaqOrIntMassSurfaceLast = SurfNum - 1; - } - if ((state.dataHeatBal->Zone(ZoneNum).TDDDomeFirst == 0) && - (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::TDD_Dome)) { - // Window surfaces are grouped last within each zone - state.dataHeatBal->Zone(ZoneNum).TDDDomeFirst = SurfNum; - if (state.dataHeatBal->Zone(ZoneNum).WindowSurfaceFirst != 0) { - state.dataHeatBal->Zone(ZoneNum).WindowSurfaceLast = SurfNum - 1; - } else { - // No window in the zone. - state.dataHeatBal->Zone(ZoneNum).OpaqOrIntMassSurfaceLast = SurfNum - 1; - state.dataHeatBal->Zone(ZoneNum).WindowSurfaceLast = -1; + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int SurfNum = 1; SurfNum <= MovedSurfs; ++SurfNum) { // TotSurfaces + if (state.dataSurface->Surface(SurfNum).spaceNum == spaceNum) { + if (thisSpace.AllSurfaceFirst == 0) { + thisSpace.AllSurfaceFirst = SurfNum; + } + if (state.dataSurface->Surface(SurfNum).IsAirBoundarySurf) { + state.dataSurface->Surface(SurfNum).HeatTransSurf = false; + continue; + } + if (thisSpace.HTSurfaceFirst == 0) { + thisSpace.HTSurfaceFirst = SurfNum; + // Non window surfaces are grouped next within each zone + thisSpace.OpaqOrIntMassSurfaceFirst = SurfNum; + } + if ((thisSpace.WindowSurfaceFirst == 0) && + ((state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window) || + (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::GlassDoor) || + (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::TDD_Diffuser))) { + // Window surfaces are grouped last within each zone + thisSpace.WindowSurfaceFirst = SurfNum; + thisSpace.OpaqOrIntMassSurfaceLast = SurfNum - 1; + } + if ((thisSpace.TDDDomeFirst == 0) && (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::TDD_Dome)) { + // Window surfaces are grouped last within each zone + thisSpace.TDDDomeFirst = SurfNum; + if (thisSpace.WindowSurfaceFirst != 0) { + thisSpace.WindowSurfaceLast = SurfNum - 1; + } else { + // No window in the zone. + thisSpace.OpaqOrIntMassSurfaceLast = SurfNum - 1; + thisSpace.WindowSurfaceLast = -1; + } + break; } - break; } } } + int firstSpaceNum = state.dataHeatBal->Zone(ZoneNum).spaceIndexes(1); + state.dataHeatBal->Zone(ZoneNum).AllSurfaceFirst = state.dataHeatBal->space(firstSpaceNum).AllSurfaceFirst; } // Surface First pointers are set, set last if (state.dataGlobal->NumOfZones > 0) { state.dataHeatBal->Zone(state.dataGlobal->NumOfZones).AllSurfaceLast = state.dataSurface->TotSurfaces; + int lastSpaceNum = state.dataHeatBal->Zone(state.dataGlobal->NumOfZones) + .spaceIndexes(state.dataHeatBal->Zone(state.dataGlobal->NumOfZones).spaceIndexes.size()); + state.dataHeatBal->space(lastSpaceNum).AllSurfaceLast = state.dataSurface->TotSurfaces; } - for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones - 1; ++ZoneNum) { - state.dataHeatBal->Zone(ZoneNum).AllSurfaceLast = state.dataHeatBal->Zone(ZoneNum + 1).AllSurfaceFirst - 1; + for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { + if (ZoneNum < state.dataGlobal->NumOfZones) { + state.dataHeatBal->Zone(ZoneNum).AllSurfaceLast = state.dataHeatBal->Zone(ZoneNum + 1).AllSurfaceFirst - 1; + } + auto &thisSpaceList = state.dataHeatBal->Zone(ZoneNum).spaceIndexes; + int numSpacesInZone = thisSpaceList.size(); + if (numSpacesInZone > 1) { + for (int spaceCount = 1; spaceCount <= numSpacesInZone - 1; ++spaceCount) { + auto &thisSpace = state.dataHeatBal->space(thisSpaceList(spaceCount)); + auto &nextSpace = state.dataHeatBal->space(thisSpaceList(spaceCount + 1)); + thisSpace.AllSurfaceLast = nextSpace.AllSurfaceFirst - 1; + } + state.dataHeatBal->space(thisSpaceList(numSpacesInZone)).AllSurfaceLast = state.dataHeatBal->Zone(ZoneNum).AllSurfaceLast; + } else if (numSpacesInZone == 1) { + auto &thisSpace = state.dataHeatBal->space(thisSpaceList(numSpacesInZone)); + thisSpace.AllSurfaceFirst = state.dataHeatBal->Zone(ZoneNum).AllSurfaceFirst; + thisSpace.AllSurfaceLast = state.dataHeatBal->Zone(ZoneNum).AllSurfaceLast; + } } for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { - if (state.dataSurface->Surface(state.dataHeatBal->Zone(ZoneNum).AllSurfaceLast).Class == DataSurfaces::SurfaceClass::TDD_Dome) { - state.dataHeatBal->Zone(ZoneNum).TDDDomeLast = state.dataHeatBal->Zone(ZoneNum).AllSurfaceLast; - } else if ((state.dataSurface->Surface(state.dataHeatBal->Zone(ZoneNum).AllSurfaceLast).Class == DataSurfaces::SurfaceClass::Window) || - (state.dataSurface->Surface(state.dataHeatBal->Zone(ZoneNum).AllSurfaceLast).Class == DataSurfaces::SurfaceClass::GlassDoor) || - (state.dataSurface->Surface(state.dataHeatBal->Zone(ZoneNum).AllSurfaceLast).Class == - DataSurfaces::SurfaceClass::TDD_Diffuser)) { - state.dataHeatBal->Zone(ZoneNum).TDDDomeLast = -1; - state.dataHeatBal->Zone(ZoneNum).WindowSurfaceLast = state.dataHeatBal->Zone(ZoneNum).AllSurfaceLast; - } else { - // If there are no windows in the zone, then set this to -1 so any for loops on WindowSurfaceFirst to WindowSurfaceLast will not - // execute. Same for TDDDome and its indices - state.dataHeatBal->Zone(ZoneNum).TDDDomeLast = -1; - state.dataHeatBal->Zone(ZoneNum).WindowSurfaceLast = -1; - state.dataHeatBal->Zone(ZoneNum).OpaqOrIntMassSurfaceLast = state.dataHeatBal->Zone(ZoneNum).AllSurfaceLast; + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + if (state.dataSurface->Surface(thisSpace.AllSurfaceLast).Class == DataSurfaces::SurfaceClass::TDD_Dome) { + thisSpace.TDDDomeLast = thisSpace.AllSurfaceLast; + } else if ((state.dataSurface->Surface(thisSpace.AllSurfaceLast).Class == DataSurfaces::SurfaceClass::Window) || + (state.dataSurface->Surface(thisSpace.AllSurfaceLast).Class == DataSurfaces::SurfaceClass::GlassDoor) || + (state.dataSurface->Surface(thisSpace.AllSurfaceLast).Class == DataSurfaces::SurfaceClass::TDD_Diffuser)) { + thisSpace.TDDDomeLast = -1; + thisSpace.WindowSurfaceLast = thisSpace.AllSurfaceLast; + } else { + // If there are no windows in the zone, then set this to -1 so any for loops on WindowSurfaceFirst to WindowSurfaceLast + // will not execute. Same for TDDDome and its indices + thisSpace.TDDDomeLast = -1; + thisSpace.WindowSurfaceLast = -1; + thisSpace.OpaqOrIntMassSurfaceLast = thisSpace.AllSurfaceLast; + } + thisSpace.OpaqOrWinSurfaceFirst = thisSpace.HTSurfaceFirst; + thisSpace.OpaqOrWinSurfaceLast = std::max(thisSpace.OpaqOrIntMassSurfaceLast, thisSpace.WindowSurfaceLast); + thisSpace.HTSurfaceLast = thisSpace.AllSurfaceLast; } - state.dataHeatBal->Zone(ZoneNum).OpaqOrWinSurfaceFirst = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst; - state.dataHeatBal->Zone(ZoneNum).OpaqOrWinSurfaceLast = - std::max(state.dataHeatBal->Zone(ZoneNum).OpaqOrIntMassSurfaceLast, state.dataHeatBal->Zone(ZoneNum).WindowSurfaceLast); - state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast = state.dataHeatBal->Zone(ZoneNum).AllSurfaceLast; } for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { - if (state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst == 0) { - ShowSevereError(state, std::string{RoutineName} + "Zone has no surfaces, Zone=" + state.dataHeatBal->Zone(ZoneNum).Name); - SurfError = true; + int zoneSurfCount = 0; + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + if (thisSpace.HTSurfaceFirst > 0) { + zoneSurfCount += (thisSpace.HTSurfaceLast - thisSpace.HTSurfaceFirst + 1); + } + if (zoneSurfCount == 0) { + ShowSevereError(state, + std::string{RoutineName} + "Zone has no heat transfer surfaces, Zone=" + state.dataHeatBal->Zone(ZoneNum).Name); + SurfError = true; + } } } @@ -2362,16 +2393,19 @@ namespace SurfaceGeometry { Real64 constexpr floorAreaPercentTolerance(floorAreaTolerance * 100.0); if (!SurfError) { for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { - for (int SurfNum = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst; SurfNum <= state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast; - ++SurfNum) { - if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Floor) { - state.dataHeatBal->Zone(ZoneNum).HasFloor = true; - int spaceNum = state.dataSurface->Surface(SurfNum).spaceNum; - state.dataHeatBal->space(spaceNum).calcFloorArea += state.dataSurface->Surface(SurfNum).Area; - } - if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Roof) { - state.dataHeatBal->Zone(ZoneNum).CeilingArea += state.dataSurface->Surface(SurfNum).Area; - state.dataHeatBal->Zone(ZoneNum).HasRoof = true; + auto &thisZone = state.dataHeatBal->Zone(ZoneNum); + for (int spaceNum : thisZone.spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { + auto &thisSurf = state.dataSurface->Surface(SurfNum); + if (thisSurf.Class == SurfaceClass::Floor) { + thisZone.HasFloor = true; + state.dataHeatBal->space(spaceNum).calcFloorArea += thisSurf.Area; + } + if (thisSurf.Class == SurfaceClass::Roof) { + thisZone.CeilingArea += thisSurf.Area; + thisZone.HasRoof = true; + } } } } @@ -2404,12 +2438,11 @@ namespace SurfaceGeometry { std::string(RoutineName), state.dataHeatBal->space(spaceNum).Name, diffp * 100.0)); - ShowContinueError( - state, - format( - "Entered Space Floor Area={:.2R}, Calculated Space Floor Area={:.2R}, entered Floor Area will be used.", - state.dataHeatBal->space(spaceNum).userEnteredFloorArea, - state.dataHeatBal->space(spaceNum).calcFloorArea)); + ShowContinueError(state, + format("Entered Space Floor Area={:.2R}, Calculated Space Floor Area={:.2R}, entered " + "Floor Area will be used.", + state.dataHeatBal->space(spaceNum).userEnteredFloorArea, + state.dataHeatBal->space(spaceNum).calcFloorArea)); } } } @@ -2447,12 +2480,12 @@ namespace SurfaceGeometry { } if (state.dataGlobal->DisplayExtraWarnings) { // Warn user of using specified Zone Floor Area - ShowWarningError( - state, - format("{}Entered Floor Area for Zone=\"{}\" is {:.1R}% different from the sum of the Space Floor Area(s).", - std::string(RoutineName), - state.dataHeatBal->Zone(ZoneNum).Name, - diffp * 100.0)); + ShowWarningError(state, + format("{}Entered Floor Area for Zone=\"{}\" is {:.1R}% different from the sum of the " + "Space Floor Area(s).", + std::string(RoutineName), + state.dataHeatBal->Zone(ZoneNum).Name, + diffp * 100.0)); ShowContinueError(state, format("Entered Zone Floor Area={:.2R}, Sum of Space Floor Area(s)={:.2R}", state.dataHeatBal->Zone(ZoneNum).UserEnteredFloorArea, @@ -2495,6 +2528,15 @@ namespace SurfaceGeometry { } else { state.dataHeatBal->Zone(ZoneNum).FloorArea = state.dataHeatBal->Zone(ZoneNum).CalcFloorArea; } + Real64 totSpacesFloorArea = 0.0; + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + totSpacesFloorArea += state.dataHeatBal->space(spaceNum).floorArea; + } + if (totSpacesFloorArea > 0.0) { + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + state.dataHeatBal->space(spaceNum).fracZoneFloorArea = state.dataHeatBal->space(spaceNum).floorArea / totSpacesFloorArea; + } + } // else leave fractions at zero } } @@ -2544,352 +2586,364 @@ namespace SurfaceGeometry { state.dataSurface->AnyMovableSlat = true; state.dataHeatBalSurf->SurfMovSlatsIndexList.push_back(SurfNum); } - } - ConstrNumSh = state.dataSurface->Surface(SurfNum).activeShadedConstruction; - if (ConstrNumSh <= 0) continue; - - WinShadingType ShadingType = state.dataSurface->WindowShadingControl(WinShadingControlPtr).ShadingType; - - // only for blinds - if (ANY_BLIND(ShadingType)) { - - // TH 1/7/2010. CR 7930 - // The old code did not consider between-glass blind. Also there should not be two blinds - both interior and exterior - // Use the new generic code (assuming only one blind) as follows - for (iTmp1 = 1; iTmp1 <= state.dataConstruction->Construct(ConstrNumSh).TotLayers; ++iTmp1) { - iTmp2 = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(iTmp1); - if (state.dataMaterial->Material(iTmp2).Group == DataHeatBalance::MaterialGroup::WindowBlind) { - BlNum = state.dataMaterial->Material(iTmp2).BlindDataPtr; - state.dataSurface->SurfWinBlindNumber(SurfNum) = BlNum; - // TH 2/18/2010. CR 8010 - // if it is a blind with movable slats, create one new blind and set it to VariableSlat if not done so yet. - // the new blind is created only once, it can be shared by multiple windows though. - if (state.dataSurface->SurfWinMovableSlats(SurfNum) && - state.dataHeatBal->Blind(BlNum).SlatAngleType != DataWindowEquivalentLayer::AngleType::Variable) { - errFlag = false; - AddVariableSlatBlind(state, BlNum, BlNumNew, errFlag); - // point to the new blind - state.dataMaterial->Material(iTmp2).BlindDataPtr = BlNumNew; - // window surface points to new blind - state.dataSurface->SurfWinBlindNumber(SurfNum) = BlNumNew; + ConstrNumSh = state.dataSurface->Surface(SurfNum).activeShadedConstruction; + if (ConstrNumSh <= 0) continue; + + WinShadingType ShadingType = state.dataSurface->WindowShadingControl(WinShadingControlPtr).ShadingType; + + // only for blinds + if (ANY_BLIND(ShadingType)) { + + // TH 1/7/2010. CR 7930 + // The old code did not consider between-glass blind. Also there should not be two blinds - both interior and exterior + // Use the new generic code (assuming only one blind) as follows + for (iTmp1 = 1; iTmp1 <= state.dataConstruction->Construct(ConstrNumSh).TotLayers; ++iTmp1) { + iTmp2 = state.dataConstruction->Construct(ConstrNumSh).LayerPoint(iTmp1); + if (state.dataMaterial->Material(iTmp2).Group == DataHeatBalance::MaterialGroup::WindowBlind) { + BlNum = state.dataMaterial->Material(iTmp2).BlindDataPtr; + state.dataSurface->SurfWinBlindNumber(SurfNum) = BlNum; + // TH 2/18/2010. CR 8010 + // if it is a blind with movable slats, create one new blind and set it to VariableSlat if not done so yet. + // the new blind is created only once, it can be shared by multiple windows though. + if (state.dataSurface->SurfWinMovableSlats(SurfNum) && + state.dataHeatBal->Blind(BlNum).SlatAngleType != DataWindowEquivalentLayer::AngleType::Variable) { + errFlag = false; + AddVariableSlatBlind(state, BlNum, BlNumNew, errFlag); + // point to the new blind + state.dataMaterial->Material(iTmp2).BlindDataPtr = BlNumNew; + // window surface points to new blind + state.dataSurface->SurfWinBlindNumber(SurfNum) = BlNumNew; + } + break; } - break; } - } - if (errFlag) { - ErrorsFound = true; - ShowContinueError(state, - "WindowShadingControl " + state.dataSurface->WindowShadingControl(WinShadingControlPtr).Name + - " has errors, program will terminate."); + if (errFlag) { + ErrorsFound = true; + ShowContinueError(state, + "WindowShadingControl " + state.dataSurface->WindowShadingControl(WinShadingControlPtr).Name + + " has errors, program will terminate."); + } } - } - } // End of surface loop + } // End of surface loop - // final associate fenestration surfaces referenced in WindowShadingControl - FinalAssociateWindowShadingControlFenestration(state, ErrorsFound); - CheckWindowShadingControlSimilarForWindow(state, ErrorsFound); - } + // final associate fenestration surfaces referenced in WindowShadingControl + FinalAssociateWindowShadingControlFenestration(state, ErrorsFound); + CheckWindowShadingControlSimilarForWindow(state, ErrorsFound); + } - // Check for zones with not enough surfaces - for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { - OpaqueHTSurfs = 0; - OpaqueHTSurfsWithWin = 0; - InternalMassSurfs = 0; - if (state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst == 0) continue; // Zone with no surfaces - for (int SurfNum = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst; SurfNum <= state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast; - ++SurfNum) { - if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Floor || - state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Wall || - state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Roof) - ++OpaqueHTSurfs; - if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::IntMass) ++InternalMassSurfs; - if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Window) { - // Count base surface only once for multiple windows on a wall - if (SurfNum > 1 && state.dataSurface->Surface(SurfNum - 1).Class != SurfaceClass::Window) ++OpaqueHTSurfsWithWin; + // Check for zones with not enough surfaces + for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { + int OpaqueHTSurfs = 0; // Number of floors, walls and roofs in a zone + int OpaqueHTSurfsWithWin = 0; // Number of floors, walls and roofs with windows in a zone + int InternalMassSurfs = 0; // Number of internal mass surfaces in a zone + int priorBaseSurfNum = 0; + + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + if (thisSpace.HTSurfaceFirst == 0) continue; // Zone with no surfaces + for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { + auto &thisSurf = state.dataSurface->Surface(SurfNum); + if (thisSurf.Class == SurfaceClass::Floor || thisSurf.Class == SurfaceClass::Wall || thisSurf.Class == SurfaceClass::Roof) + ++OpaqueHTSurfs; + if (thisSurf.Class == SurfaceClass::IntMass) ++InternalMassSurfs; + if (thisSurf.Class == SurfaceClass::Window) { + // Count base surface only once for multiple windows on a wall + int thisBaseSurfNum = thisSurf.BaseSurf; + if (thisBaseSurfNum != priorBaseSurfNum) { + ++OpaqueHTSurfsWithWin; + priorBaseSurfNum = thisBaseSurfNum; + } + } + } + } + if (OpaqueHTSurfsWithWin == 1 && OpaqueHTSurfs == 1 && InternalMassSurfs == 0) { + SurfError = true; + ShowSevereError(state, + std::string{RoutineName} + "Zone " + state.dataHeatBal->Zone(ZoneNum).Name + + " has only one floor, wall or roof, and this surface has a window."); + ShowContinueError(state, "Add more floors, walls or roofs, or an internal mass surface."); } } - if (OpaqueHTSurfsWithWin == 1 && OpaqueHTSurfs == 1 && InternalMassSurfs == 0) { - SurfError = true; - ShowSevereError(state, - std::string{RoutineName} + "Zone " + state.dataHeatBal->Zone(ZoneNum).Name + - " has only one floor, wall or roof, and this surface has a window."); - ShowContinueError(state, "Add more floors, walls or roofs, or an internal mass surface."); - } - } - // set up vertex of centroid for each surface. - CalcSurfaceCentroid(state); + // set up vertex of centroid for each surface. + CalcSurfaceCentroid(state); - SetupShadeSurfacesForSolarCalcs(state); // if shading surfaces are solar collectors or PV, then we need full solar calc. + SetupShadeSurfacesForSolarCalcs(state); // if shading surfaces are solar collectors or PV, then we need full solar calc. - GetMovableInsulationData(state, ErrorsFound); + GetMovableInsulationData(state, ErrorsFound); - if (state.dataSurface->CalcSolRefl) GetShadingSurfReflectanceData(state, ErrorsFound); + if (state.dataSurface->CalcSolRefl) GetShadingSurfReflectanceData(state, ErrorsFound); - LayNumOutside = 0; - for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) { - // Check for EcoRoof and only 1 allowed to be used. - if (state.dataSurface->Surface(SurfNum).Construction > 0) - state.dataSurface->SurfExtEcoRoof(SurfNum) = - state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).TypeIsEcoRoof; - if (!state.dataSurface->SurfExtEcoRoof(SurfNum)) continue; - if (LayNumOutside == 0) { - LayNumOutside = state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).LayerPoint(1); - continue; - } - if (LayNumOutside != state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).LayerPoint(1)) { - ShowSevereError(state, std::string{RoutineName} + "Only one EcoRoof Material is currently allowed for all constructions."); - ShowContinueError(state, "... first material=" + state.dataMaterial->Material(LayNumOutside).Name); - ShowContinueError( - state, - "... conflicting Construction=" + state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).Name + - " uses material=" + - state.dataMaterial - ->Material(state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).LayerPoint(1)) - .Name); - ErrorsFound = true; + LayNumOutside = 0; + for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) { + // Check for EcoRoof and only 1 allowed to be used. + if (state.dataSurface->Surface(SurfNum).Construction > 0) + state.dataSurface->SurfExtEcoRoof(SurfNum) = + state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).TypeIsEcoRoof; + if (!state.dataSurface->SurfExtEcoRoof(SurfNum)) continue; + if (LayNumOutside == 0) { + LayNumOutside = state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).LayerPoint(1); + continue; + } + if (LayNumOutside != state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).LayerPoint(1)) { + ShowSevereError(state, std::string{RoutineName} + "Only one EcoRoof Material is currently allowed for all constructions."); + ShowContinueError(state, "... first material=" + state.dataMaterial->Material(LayNumOutside).Name); + ShowContinueError( + state, + "... conflicting Construction=" + state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).Name + + " uses material=" + + state.dataMaterial + ->Material(state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).LayerPoint(1)) + .Name); + ErrorsFound = true; + } } - } - // Reserve space to avoid excess allocations - state.dataSurface->AllHTSurfaceList.reserve(state.dataSurface->TotSurfaces); - state.dataSurface->AllExtSolarSurfaceList.reserve(state.dataSurface->TotSurfaces); - state.dataSurface->AllShadowPossObstrSurfaceList.reserve(state.dataSurface->TotSurfaces); - state.dataSurface->AllIZSurfaceList.reserve(state.dataSurface->TotSurfaces); - state.dataSurface->AllHTNonWindowSurfaceList.reserve(state.dataSurface->TotSurfaces - state.dataSurface->TotWindows); - state.dataSurface->AllHTWindowSurfaceList.reserve(state.dataSurface->TotWindows); - state.dataSurface->AllExtSolWindowSurfaceList.reserve(state.dataSurface->TotWindows); - state.dataSurface->AllExtSolWinWithFrameSurfaceList.reserve(state.dataSurface->TotWindows); - state.dataSurface->AllHTKivaSurfaceList.reserve(state.dataSurface->TotSurfaces); - - // Set flag that determines whether a surface can be an exterior obstruction - // Also set associated surfaces for Kiva foundations and build heat transfer surface lists - for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) { - state.dataSurface->Surface(SurfNum).IsShadowPossibleObstruction = false; - if (state.dataSurface->Surface(SurfNum).ExtSolar) { - // This may include some attached shading surfaces - state.dataSurface->AllExtSolarSurfaceList.push_back(SurfNum); - } - if (state.dataSurface->Surface(SurfNum).HeatTransSurf) { - // Outside light shelves get tagged later as HeatTransSurf=true but they haven't been processed yet - state.dataSurface->AllHTSurfaceList.push_back(SurfNum); - int const zoneNum(state.dataSurface->Surface(SurfNum).Zone); - auto &surfZone(state.dataHeatBal->Zone(zoneNum)); - surfZone.ZoneHTSurfaceList.push_back(SurfNum); - // Sort window vs non-window surfaces - if (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window) { - state.dataSurface->AllHTWindowSurfaceList.push_back(SurfNum); - surfZone.ZoneHTWindowSurfaceList.push_back(SurfNum); - if (state.dataSurface->Surface(SurfNum).ExtSolar) { - state.dataSurface->AllExtSolWindowSurfaceList.push_back(SurfNum); - if (state.dataSurface->Surface(SurfNum).FrameDivider > 0) { - state.dataSurface->AllExtSolWinWithFrameSurfaceList.push_back(SurfNum); - } - } - } else { - state.dataSurface->AllHTNonWindowSurfaceList.push_back(SurfNum); - surfZone.ZoneHTNonWindowSurfaceList.push_back(SurfNum); - } - int const surfExtBoundCond(state.dataSurface->Surface(SurfNum).ExtBoundCond); - // Build zone and interzone surface lists - if ((surfExtBoundCond > 0) && (surfExtBoundCond != SurfNum)) { - state.dataSurface->AllIZSurfaceList.push_back(SurfNum); - surfZone.ZoneIZSurfaceList.push_back(SurfNum); - auto &adjZone(state.dataHeatBal->Zone(state.dataSurface->Surface(surfExtBoundCond).Zone)); - adjZone.ZoneHTSurfaceList.push_back(SurfNum); - adjZone.ZoneIZSurfaceList.push_back(SurfNum); + // Reserve space to avoid excess allocations + state.dataSurface->AllHTSurfaceList.reserve(state.dataSurface->TotSurfaces); + state.dataSurface->AllExtSolarSurfaceList.reserve(state.dataSurface->TotSurfaces); + state.dataSurface->AllShadowPossObstrSurfaceList.reserve(state.dataSurface->TotSurfaces); + state.dataSurface->AllIZSurfaceList.reserve(state.dataSurface->TotSurfaces); + state.dataSurface->AllHTNonWindowSurfaceList.reserve(state.dataSurface->TotSurfaces - state.dataSurface->TotWindows); + state.dataSurface->AllHTWindowSurfaceList.reserve(state.dataSurface->TotWindows); + state.dataSurface->AllExtSolWindowSurfaceList.reserve(state.dataSurface->TotWindows); + state.dataSurface->AllExtSolWinWithFrameSurfaceList.reserve(state.dataSurface->TotWindows); + state.dataSurface->AllHTKivaSurfaceList.reserve(state.dataSurface->TotSurfaces); + + // Set flag that determines whether a surface can be an exterior obstruction + // Also set associated surfaces for Kiva foundations and build heat transfer surface lists + for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) { + state.dataSurface->Surface(SurfNum).IsShadowPossibleObstruction = false; + if (state.dataSurface->Surface(SurfNum).ExtSolar) { + // This may include some attached shading surfaces + state.dataSurface->AllExtSolarSurfaceList.push_back(SurfNum); + } + if (state.dataSurface->Surface(SurfNum).HeatTransSurf) { + // Outside light shelves get tagged later as HeatTransSurf=true but they haven't been processed yet + state.dataSurface->AllHTSurfaceList.push_back(SurfNum); + int const zoneNum(state.dataSurface->Surface(SurfNum).Zone); + auto &surfZone(state.dataHeatBal->Zone(zoneNum)); + surfZone.ZoneHTSurfaceList.push_back(SurfNum); // Sort window vs non-window surfaces if (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window) { - adjZone.ZoneHTWindowSurfaceList.push_back(SurfNum); + state.dataSurface->AllHTWindowSurfaceList.push_back(SurfNum); + surfZone.ZoneHTWindowSurfaceList.push_back(SurfNum); + if (state.dataSurface->Surface(SurfNum).ExtSolar) { + state.dataSurface->AllExtSolWindowSurfaceList.push_back(SurfNum); + if (state.dataSurface->Surface(SurfNum).FrameDivider > 0) { + state.dataSurface->AllExtSolWinWithFrameSurfaceList.push_back(SurfNum); + } + } } else { - adjZone.ZoneHTNonWindowSurfaceList.push_back(SurfNum); + state.dataSurface->AllHTNonWindowSurfaceList.push_back(SurfNum); + surfZone.ZoneHTNonWindowSurfaceList.push_back(SurfNum); + } + int const surfExtBoundCond(state.dataSurface->Surface(SurfNum).ExtBoundCond); + // Build zone and interzone surface lists + if ((surfExtBoundCond > 0) && (surfExtBoundCond != SurfNum)) { + state.dataSurface->AllIZSurfaceList.push_back(SurfNum); + surfZone.ZoneIZSurfaceList.push_back(SurfNum); + auto &adjZone(state.dataHeatBal->Zone(state.dataSurface->Surface(surfExtBoundCond).Zone)); + adjZone.ZoneHTSurfaceList.push_back(SurfNum); + adjZone.ZoneIZSurfaceList.push_back(SurfNum); + // Sort window vs non-window surfaces + if (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window) { + adjZone.ZoneHTWindowSurfaceList.push_back(SurfNum); + } else { + adjZone.ZoneHTNonWindowSurfaceList.push_back(SurfNum); + } } } - } - // Exclude non-exterior heat transfer surfaces (but not OtherSideCondModeledExt = -4 CR7640) - if (state.dataSurface->Surface(SurfNum).HeatTransSurf && state.dataSurface->Surface(SurfNum).ExtBoundCond > 0) continue; - if (state.dataSurface->Surface(SurfNum).HeatTransSurf && state.dataSurface->Surface(SurfNum).ExtBoundCond == Ground) continue; - if (state.dataSurface->Surface(SurfNum).HeatTransSurf && state.dataSurface->Surface(SurfNum).ExtBoundCond == KivaFoundation) { - state.dataSurface->AllHTKivaSurfaceList.push_back(SurfNum); - if (!ErrorsFound) - state.dataSurfaceGeometry->kivaManager.foundationInputs[state.dataSurface->Surface(SurfNum).OSCPtr].surfaces.push_back(SurfNum); - continue; - } - if (state.dataSurface->Surface(SurfNum).HeatTransSurf && state.dataSurface->Surface(SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt) - continue; - if (state.dataSurface->Surface(SurfNum).HeatTransSurf && state.dataSurface->Surface(SurfNum).ExtBoundCond == OtherSideCoefCalcExt) - continue; - // Exclude windows and doors, i.e., consider only their base surfaces as possible obstructions - if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Window || state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Door) - continue; - // Exclude duplicate shading surfaces - if (state.dataSurface->Surface(SurfNum).MirroredSurf) continue; - // Exclude air boundary surfaces - if (state.dataSurface->Surface(SurfNum).IsAirBoundarySurf) continue; + // Exclude non-exterior heat transfer surfaces (but not OtherSideCondModeledExt = -4 CR7640) + if (state.dataSurface->Surface(SurfNum).HeatTransSurf && state.dataSurface->Surface(SurfNum).ExtBoundCond > 0) continue; + if (state.dataSurface->Surface(SurfNum).HeatTransSurf && state.dataSurface->Surface(SurfNum).ExtBoundCond == Ground) continue; + if (state.dataSurface->Surface(SurfNum).HeatTransSurf && state.dataSurface->Surface(SurfNum).ExtBoundCond == KivaFoundation) { + state.dataSurface->AllHTKivaSurfaceList.push_back(SurfNum); + if (!ErrorsFound) + state.dataSurfaceGeometry->kivaManager.foundationInputs[state.dataSurface->Surface(SurfNum).OSCPtr].surfaces.push_back( + SurfNum); + continue; + } + if (state.dataSurface->Surface(SurfNum).HeatTransSurf && state.dataSurface->Surface(SurfNum).ExtBoundCond == OtherSideCoefNoCalcExt) + continue; + if (state.dataSurface->Surface(SurfNum).HeatTransSurf && state.dataSurface->Surface(SurfNum).ExtBoundCond == OtherSideCoefCalcExt) + continue; + // Exclude windows and doors, i.e., consider only their base surfaces as possible obstructions + if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Window || + state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Door) + continue; + // Exclude duplicate shading surfaces + if (state.dataSurface->Surface(SurfNum).MirroredSurf) continue; + // Exclude air boundary surfaces + if (state.dataSurface->Surface(SurfNum).IsAirBoundarySurf) continue; - state.dataSurface->Surface(SurfNum).IsShadowPossibleObstruction = true; - state.dataSurface->AllShadowPossObstrSurfaceList.push_back(SurfNum); - } + state.dataSurface->Surface(SurfNum).IsShadowPossibleObstruction = true; + state.dataSurface->AllShadowPossObstrSurfaceList.push_back(SurfNum); + } - // Check for IRT surfaces in invalid places. - iTmp1 = 0; - if (std::any_of(state.dataConstruction->Construct.begin(), - state.dataConstruction->Construct.end(), - [](Construction::ConstructionProps const &e) { return e.TypeIsIRT; })) { - for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) { - if (!state.dataSurface->Surface(SurfNum).HeatTransSurf) continue; // ignore shading surfaces - if (state.dataSurface->Surface(SurfNum).ExtBoundCond > 0 && state.dataSurface->Surface(SurfNum).ExtBoundCond != SurfNum) - continue; // interzone, not adiabatic surface - if (!state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).TypeIsIRT) { - continue; + // Check for IRT surfaces in invalid places. + iTmp1 = 0; + if (std::any_of(state.dataConstruction->Construct.begin(), + state.dataConstruction->Construct.end(), + [](Construction::ConstructionProps const &e) { return e.TypeIsIRT; })) { + for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; ++SurfNum) { + if (!state.dataSurface->Surface(SurfNum).HeatTransSurf) continue; // ignore shading surfaces + if (state.dataSurface->Surface(SurfNum).ExtBoundCond > 0 && state.dataSurface->Surface(SurfNum).ExtBoundCond != SurfNum) + continue; // interzone, not adiabatic surface + if (!state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).TypeIsIRT) { + continue; + } + if (!state.dataGlobal->DisplayExtraWarnings) { + ++iTmp1; + } else { + ShowWarningError(state, + std::string{RoutineName} + "Surface=\"" + state.dataSurface->Surface(SurfNum).Name + + "\" uses InfraredTransparent construction in a non-interzone surface. (illegal use)"); + } } - if (!state.dataGlobal->DisplayExtraWarnings) { - ++iTmp1; - } else { - ShowWarningError(state, - std::string{RoutineName} + "Surface=\"" + state.dataSurface->Surface(SurfNum).Name + - "\" uses InfraredTransparent construction in a non-interzone surface. (illegal use)"); + if (iTmp1 > 0) { + ShowWarningError( + state, + format("{}Surfaces use InfraredTransparent constructions {} in non-interzone surfaces. (illegal use)", RoutineName, iTmp1)); + ShowContinueError(state, "For explicit details on each use, use Output:Diagnostics,DisplayExtraWarnings;"); } } - if (iTmp1 > 0) { - ShowWarningError( - state, - format("{}Surfaces use InfraredTransparent constructions {} in non-interzone surfaces. (illegal use)", RoutineName, iTmp1)); - ShowContinueError(state, "For explicit details on each use, use Output:Diagnostics,DisplayExtraWarnings;"); - } - } - // Note, could do same for Window Area and detecting if Interzone Surface in Zone + // Note, could do same for Window Area and detecting if Interzone Surface in Zone - if (state.dataSurfaceGeometry->Warning1Count > 0) { - ShowWarningMessage(state, - format("{}Window dimensions differ from Window 5/6 data file dimensions, {} times.", - RoutineName, - state.dataSurfaceGeometry->Warning1Count)); - ShowContinueError(state, "This will affect the frame heat transfer calculation if the frame in the Data File entry"); - ShowContinueError(state, "is not uniform, i.e., has sections with different geometry and/or thermal properties."); - ShowContinueError(state, "For explicit details on each window, use Output:Diagnostics,DisplayExtraWarnings;"); - } - if (state.dataSurfaceGeometry->Warning2Count > 0) { - ShowWarningMessage(state, - format("{}Exterior Windows have been replaced with Window 5/6 two glazing systems, {} times.", - RoutineName, - state.dataSurfaceGeometry->Warning2Count)); - ShowContinueError(state, "Note that originally entered dimensions are overridden."); - ShowContinueError(state, "For explicit details on each window, use Output:Diagnostics,DisplayExtraWarnings;"); - } - if (state.dataSurfaceGeometry->Warning3Count > 0) { - ShowWarningMessage(state, - format("{}Interior Windows have been replaced with Window 5/6 two glazing systems, {} times.", - RoutineName, - state.dataSurfaceGeometry->Warning3Count)); - ShowContinueError(state, "Note that originally entered dimensions are overridden."); - ShowContinueError(state, "For explicit details on each window, use Output:Diagnostics,DisplayExtraWarnings;"); - } + if (state.dataSurfaceGeometry->Warning1Count > 0) { + ShowWarningMessage(state, + format("{}Window dimensions differ from Window 5/6 data file dimensions, {} times.", + RoutineName, + state.dataSurfaceGeometry->Warning1Count)); + ShowContinueError(state, "This will affect the frame heat transfer calculation if the frame in the Data File entry"); + ShowContinueError(state, "is not uniform, i.e., has sections with different geometry and/or thermal properties."); + ShowContinueError(state, "For explicit details on each window, use Output:Diagnostics,DisplayExtraWarnings;"); + } + if (state.dataSurfaceGeometry->Warning2Count > 0) { + ShowWarningMessage(state, + format("{}Exterior Windows have been replaced with Window 5/6 two glazing systems, {} times.", + RoutineName, + state.dataSurfaceGeometry->Warning2Count)); + ShowContinueError(state, "Note that originally entered dimensions are overridden."); + ShowContinueError(state, "For explicit details on each window, use Output:Diagnostics,DisplayExtraWarnings;"); + } + if (state.dataSurfaceGeometry->Warning3Count > 0) { + ShowWarningMessage(state, + format("{}Interior Windows have been replaced with Window 5/6 two glazing systems, {} times.", + RoutineName, + state.dataSurfaceGeometry->Warning3Count)); + ShowContinueError(state, "Note that originally entered dimensions are overridden."); + ShowContinueError(state, "For explicit details on each window, use Output:Diagnostics,DisplayExtraWarnings;"); + } - if (state.dataErrTracking->TotalMultipliedWindows > 0) { - ShowWarningMessage(state, - format("{}There are {} window/glass door(s) that may cause inaccurate shadowing due to Solar Distribution.", - RoutineName, - state.dataErrTracking->TotalMultipliedWindows)); - ShowContinueError(state, "For explicit details on each window, use Output:Diagnostics,DisplayExtraWarnings;"); - state.dataErrTracking->TotalWarningErrors += state.dataErrTracking->TotalMultipliedWindows; - } - if (state.dataErrTracking->TotalCoincidentVertices > 0) { - ShowWarningMessage(state, - format("{}There are {} coincident/collinear vertices; These have been deleted unless the deletion would bring the " - "number of surface sides < 3.", - RoutineName, - state.dataErrTracking->TotalCoincidentVertices)); - ShowContinueError(state, "For explicit details on each problem surface, use Output:Diagnostics,DisplayExtraWarnings;"); - state.dataErrTracking->TotalWarningErrors += state.dataErrTracking->TotalCoincidentVertices; - } - if (state.dataErrTracking->TotalDegenerateSurfaces > 0) { - ShowSevereMessage(state, - format("{}There are {} degenerate surfaces; Degenerate surfaces are those with number of sides < 3.", - RoutineName, - state.dataErrTracking->TotalDegenerateSurfaces)); - ShowContinueError(state, "These surfaces should be deleted."); - ShowContinueError(state, "For explicit details on each problem surface, use Output:Diagnostics,DisplayExtraWarnings;"); - state.dataErrTracking->TotalSevereErrors += state.dataErrTracking->TotalDegenerateSurfaces; - } + if (state.dataErrTracking->TotalMultipliedWindows > 0) { + ShowWarningMessage(state, + format("{}There are {} window/glass door(s) that may cause inaccurate shadowing due to Solar Distribution.", + RoutineName, + state.dataErrTracking->TotalMultipliedWindows)); + ShowContinueError(state, "For explicit details on each window, use Output:Diagnostics,DisplayExtraWarnings;"); + state.dataErrTracking->TotalWarningErrors += state.dataErrTracking->TotalMultipliedWindows; + } + if (state.dataErrTracking->TotalCoincidentVertices > 0) { + ShowWarningMessage(state, + format("{}There are {} coincident/collinear vertices; These have been deleted unless the deletion would bring the " + "number of surface sides < 3.", + RoutineName, + state.dataErrTracking->TotalCoincidentVertices)); + ShowContinueError(state, "For explicit details on each problem surface, use Output:Diagnostics,DisplayExtraWarnings;"); + state.dataErrTracking->TotalWarningErrors += state.dataErrTracking->TotalCoincidentVertices; + } + if (state.dataErrTracking->TotalDegenerateSurfaces > 0) { + ShowSevereMessage(state, + format("{}There are {} degenerate surfaces; Degenerate surfaces are those with number of sides < 3.", + RoutineName, + state.dataErrTracking->TotalDegenerateSurfaces)); + ShowContinueError(state, "These surfaces should be deleted."); + ShowContinueError(state, "For explicit details on each problem surface, use Output:Diagnostics,DisplayExtraWarnings;"); + state.dataErrTracking->TotalSevereErrors += state.dataErrTracking->TotalDegenerateSurfaces; + } - GetHTSurfExtVentedCavityData(state, ErrorsFound); + GetHTSurfExtVentedCavityData(state, ErrorsFound); - state.dataSurfaceGeometry->exposedFoundationPerimeter.getData(state, ErrorsFound); + state.dataSurfaceGeometry->exposedFoundationPerimeter.getData(state, ErrorsFound); - GetSurfaceHeatTransferAlgorithmOverrides(state, ErrorsFound); + GetSurfaceHeatTransferAlgorithmOverrides(state, ErrorsFound); - // Set up enclosures, process Air Boundaries if any - SetupEnclosuresAndAirBoundaries(state, state.dataViewFactor->EnclRadInfo, SurfaceGeometry::enclosureType::RadiantEnclosures, ErrorsFound); + // Set up enclosures, process Air Boundaries if any + SetupEnclosuresAndAirBoundaries(state, state.dataViewFactor->EnclRadInfo, SurfaceGeometry::enclosureType::RadiantEnclosures, ErrorsFound); - GetSurfaceGroundSurfsData(state, ErrorsFound); + GetSurfaceGroundSurfsData(state, ErrorsFound); - GetSurfaceSrdSurfsData(state, ErrorsFound); + GetSurfaceSrdSurfsData(state, ErrorsFound); - GetSurfaceLocalEnvData(state, ErrorsFound); + GetSurfaceLocalEnvData(state, ErrorsFound); - if (SurfError || ErrorsFound) { - ErrorsFound = true; - ShowFatalError(state, std::string{RoutineName} + "Errors discovered, program terminates."); - } - - int TotShadSurf = TotDetachedFixed + TotDetachedBldg + TotRectDetachedFixed + TotRectDetachedBldg + TotShdSubs + TotOverhangs + - TotOverhangsProjection + TotFins + TotFinsProjection; - int NumDElightCmplxFen = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Daylighting:DElight:ComplexFenestration"); - if (TotShadSurf > 0 && (NumDElightCmplxFen > 0 || DaylightingManager::doesDayLightingUseDElight(state))) { - ShowWarningError(state, - std::string{RoutineName} + "When using DElight daylighting the presence of exterior shading surfaces is ignored."); - } - - for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; SurfNum++) { - // Initialize run time surface arrays - state.dataSurface->SurfActiveConstruction(SurfNum) = state.dataSurface->Surface(SurfNum).Construction; - state.dataSurface->Surface(SurfNum).RepresentativeCalcSurfNum = SurfNum; - } + if (SurfError || ErrorsFound) { + ErrorsFound = true; + ShowFatalError(state, std::string{RoutineName} + "Errors discovered, program terminates."); + } - // Representative surface calculations: Assign representative heat transfer surfaces - if (state.dataSurface->UseRepresentativeSurfaceCalculations && - state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneProperty:UserViewFactors:BySurfaceName") == 0) { - for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurf = state.dataHeatBal->Zone(zoneNum).HTSurfaceFirst; - int const lastSurf = state.dataHeatBal->Zone(zoneNum).HTSurfaceLast; - for (int surfNum = firstSurf; surfNum <= lastSurf; surfNum++) { - auto &surface(state.dataSurface->Surface(surfNum)); - // Conditions where surface always needs to be unique - bool forceUniqueSurface = - surface.HasShadeControl || state.dataSurface->SurfWinAirflowSource(surfNum) != DataSurfaces::WindowAirFlowSource::Invalid || - state.dataConstruction->Construct(surface.Construction).SourceSinkPresent || surface.Class == SurfaceClass::TDD_Dome || - (surface.Class == SurfaceClass::Window && (state.dataSurface->SurfWinOriginalClass(surfNum) == SurfaceClass::TDD_Diffuser || - state.dataSurface->SurfWinWindowModelType(surfNum) != WindowModel::Detailed || - state.dataWindowManager->inExtWindowModel->isExternalLibraryModel() || - state.dataConstruction->Construct(surface.Construction).TCFlag == 1)); - if (!forceUniqueSurface) { - state.dataSurface->Surface(surfNum).set_representative_surface(state, surfNum); + int TotShadSurf = TotDetachedFixed + TotDetachedBldg + TotRectDetachedFixed + TotRectDetachedBldg + TotShdSubs + TotOverhangs + + TotOverhangsProjection + TotFins + TotFinsProjection; + int NumDElightCmplxFen = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Daylighting:DElight:ComplexFenestration"); + if (TotShadSurf > 0 && (NumDElightCmplxFen > 0 || DaylightingManager::doesDayLightingUseDElight(state))) { + ShowWarningError(state, + std::string{RoutineName} + "When using DElight daylighting the presence of exterior shading surfaces is ignored."); + } + + for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; SurfNum++) { + // Initialize run time surface arrays + state.dataSurface->SurfActiveConstruction(SurfNum) = state.dataSurface->Surface(SurfNum).Construction; + state.dataSurface->Surface(SurfNum).RepresentativeCalcSurfNum = SurfNum; + } + + // Representative surface calculations: Assign representative heat transfer surfaces + if (state.dataSurface->UseRepresentativeSurfaceCalculations && + state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "ZoneProperty:UserViewFactors:BySurfaceName") == 0) { + for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int surfNum = thisSpace.HTSurfaceFirst; surfNum <= thisSpace.HTSurfaceLast; surfNum++) { + auto &surface(state.dataSurface->Surface(surfNum)); + // Conditions where surface always needs to be unique + bool forceUniqueSurface = + surface.HasShadeControl || + state.dataSurface->SurfWinAirflowSource(surfNum) != DataSurfaces::WindowAirFlowSource::Invalid || + state.dataConstruction->Construct(surface.Construction).SourceSinkPresent || + surface.Class == SurfaceClass::TDD_Dome || + (surface.Class == SurfaceClass::Window && + (state.dataSurface->SurfWinOriginalClass(surfNum) == SurfaceClass::TDD_Diffuser || + state.dataSurface->SurfWinWindowModelType(surfNum) != WindowModel::Detailed || + state.dataWindowManager->inExtWindowModel->isExternalLibraryModel() || + state.dataConstruction->Construct(surface.Construction).TCFlag == 1)); + if (!forceUniqueSurface) { + state.dataSurface->Surface(surfNum).set_representative_surface(state, surfNum); + } + } } } } - } - // Initialize surface with movable insulation index list - for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; SurfNum++) { - if (state.dataSurface->SurfMaterialMovInsulExt(SurfNum) > 0 || state.dataSurface->SurfMaterialMovInsulInt(SurfNum) > 0) { - state.dataHeatBalSurf->SurfMovInsulIndexList.push_back(SurfNum); + // Initialize surface with movable insulation index list + for (int SurfNum = 1; SurfNum <= state.dataSurface->TotSurfaces; SurfNum++) { + if (state.dataSurface->SurfMaterialMovInsulExt(SurfNum) > 0 || state.dataSurface->SurfMaterialMovInsulInt(SurfNum) > 0) { + state.dataHeatBalSurf->SurfMovInsulIndexList.push_back(SurfNum); + } } } } - void CreateMissingSpaces(EnergyPlusData &state, bool &ErrorsFound) + void CreateMissingSpaces(EnergyPlusData &state, Array1D &Surfaces) { - static constexpr std::string_view RoutineName("CreateMissingSpaces: "); // Scan surfaces to see if Space was assigned in input for (int surfNum = 1; surfNum <= state.dataSurface->TotSurfaces; ++surfNum) { - auto &thisSurf = state.dataSurface->Surface(surfNum); + auto &thisSurf = Surfaces(surfNum); if (!thisSurf.HeatTransSurf) continue; // ignore shading surfaces if (thisSurf.BaseSurf != surfNum) { // Set space for subsurfaces - thisSurf.spaceNum = state.dataSurface->Surface(thisSurf.BaseSurf).spaceNum; + thisSurf.spaceNum = Surfaces(thisSurf.BaseSurf).spaceNum; } if (thisSurf.spaceNum > 0) { state.dataHeatBal->Zone(thisSurf.Zone).anySurfacesWithSpace = true; @@ -2922,19 +2976,28 @@ namespace SurfaceGeometry { } } - // Assign Spaces to surfaces without one and build Space surface lists now that all of the sorting and space numbering is complete + // Assign Spaces to surfaces without one for (int surfNum = 1; surfNum <= state.dataSurface->TotSurfaces; ++surfNum) { - auto &thisSurf = state.dataSurface->Surface(surfNum); + auto &thisSurf = Surfaces(surfNum); if (!thisSurf.HeatTransSurf) continue; // ignore shading surfaces if (thisSurf.spaceNum == 0) { int const numSpaces = state.dataHeatBal->Zone(thisSurf.Zone).numSpaces; int const lastSpaceForZone = state.dataHeatBal->Zone(thisSurf.Zone).spaceIndexes(numSpaces); thisSurf.spaceNum = lastSpaceForZone; } + } + } + + void createSpaceSurfaceLists(EnergyPlusData &state, bool &ErrorsFound) + { + static constexpr std::string_view RoutineName("createSpaceSurfaceLists: "); + // Build Space surface lists now that all of the surface sorting is complete + for (int surfNum = 1; surfNum <= state.dataSurface->TotSurfaces; ++surfNum) { + auto &thisSurf = state.dataSurface->Surface(surfNum); + if (!thisSurf.HeatTransSurf) continue; // ignore shading surfaces // Add to Space's list of surfaces state.dataHeatBal->space(thisSurf.spaceNum).surfaces.emplace_back(surfNum); } - // TODO MJW: Is this necessary? Check that all Spaces have at least one Surface for (int spaceNum = 1; spaceNum < state.dataGlobal->numSpaces; ++spaceNum) { if (int(state.dataHeatBal->space(spaceNum).surfaces.size()) == 0) { @@ -2943,7 +3006,6 @@ namespace SurfaceGeometry { } } } - void checkSubSurfAzTiltNorm(EnergyPlusData &state, SurfaceData &baseSurface, // Base surface data (in) SurfaceData &subSurface, // Subsurface data (in) @@ -2960,8 +3022,8 @@ namespace SurfaceGeometry { // Check if base surface and subsurface have the same normal Vectors::CompareTwoVectors(baseSurface.NewellSurfaceNormalVector, subSurface.NewellSurfaceNormalVector, sameSurfNormal, 0.001); if (sameSurfNormal) { // copy lcs vectors - // Prior logic tested for azimuth difference < 30 and then skipped this - this caused large diffs in CmplxGlz_MeasuredDeflectionAndShading - // Restoring that check here but will require further investigation (MJW Dec 2015) + // Prior logic tested for azimuth difference < 30 and then skipped this - this caused large diffs in + // CmplxGlz_MeasuredDeflectionAndShading Restoring that check here but will require further investigation (MJW Dec 2015) if (std::abs(baseSurface.Azimuth - subSurface.Azimuth) > warningTolerance) { subSurface.lcsx = baseSurface.lcsx; subSurface.lcsy = baseSurface.lcsy; @@ -2994,10 +3056,10 @@ namespace SurfaceGeometry { (std::abs(baseSurface.Tilt - subSurface.Tilt) > warningTolerance)) { ++state.dataSurfaceGeometry->checkSubSurfAzTiltNormErrCount; if (state.dataSurfaceGeometry->checkSubSurfAzTiltNormErrCount == 1 && !state.dataGlobal->DisplayExtraWarnings) { - ShowWarningError( - state, - format("checkSubSurfAzTiltNorm: Some Outward Facing angles of subsurfaces differ more than {:.1R} degrees from base surface.", - warningTolerance)); + ShowWarningError(state, + format("checkSubSurfAzTiltNorm: Some Outward Facing angles of subsurfaces differ more than {:.1R} " + "degrees from base surface.", + warningTolerance)); ShowContinueError(state, "...use Output:Diagnostics,DisplayExtraWarnings; to show more details on individual surfaces."); } if (state.dataGlobal->DisplayExtraWarnings) { @@ -3899,9 +3961,9 @@ namespace SurfaceGeometry { "GetHTSurfaceData: Surfaces with interface to GroundFCfactorMethod found but no \"FC Ground " "Temperatures\" were input."); ShowContinueError(state, "Found first in surface=" + state.dataIPShortCut->cAlphaArgs(1)); - ShowContinueError( - state, - "Either add a \"Site:GroundTemperature:FCfactorMethod\" object or use a weather file with Ground Temperatures."); + ShowContinueError(state, + "Either add a \"Site:GroundTemperature:FCfactorMethod\" object or use a weather file with " + "Ground Temperatures."); ErrorsFound = true; state.dataSurfaceGeometry->NoFCGroundTempObjWarning = false; } @@ -4522,9 +4584,9 @@ namespace SurfaceGeometry { "GetRectSurfaces: Surfaces with interface to GroundFCfactorMethod found but no \"FC Ground " "Temperatures\" were input."); ShowContinueError(state, "Found first in surface=" + state.dataIPShortCut->cAlphaArgs(1)); - ShowContinueError( - state, - "Either add a \"Site:GroundTemperature:FCfactorMethod\" object or use a weather file with Ground Temperatures."); + ShowContinueError(state, + "Either add a \"Site:GroundTemperature:FCfactorMethod\" object or use a weather file with " + "Ground Temperatures."); ErrorsFound = true; state.dataSurfaceGeometry->NoFCGroundTempObjWarning = false; } @@ -7583,11 +7645,13 @@ namespace SurfaceGeometry { //).Area //) /// sum( Surface( ExtVentedCavity( Item ).SurfPtrs ).Area ); //Autodesk:F2C++ Array subscript usage: Replaced by below - AvgAzimuth = - sum_product_sub( - state.dataSurface->Surface, &SurfaceData::Azimuth, &SurfaceData::Area, state.dataSurface->ExtVentedCavity(Item).SurfPtrs) / - surfaceArea; // Autodesk:F2C++ Functions handle array subscript usage - // AvgTilt = sum( Surface( ExtVentedCavity( Item ).SurfPtrs ).Tilt * Surface( ExtVentedCavity( Item ).SurfPtrs ).Area ) / + AvgAzimuth = sum_product_sub(state.dataSurface->Surface, + &SurfaceData::Azimuth, + &SurfaceData::Area, + state.dataSurface->ExtVentedCavity(Item).SurfPtrs) / + surfaceArea; // Autodesk:F2C++ Functions handle array subscript usage + // AvgTilt = sum( Surface( ExtVentedCavity( Item ).SurfPtrs ).Tilt * Surface( ExtVentedCavity( Item ).SurfPtrs ).Area ) + // / // sum( Surface( ExtVentedCavity( Item ).SurfPtrs ).Area ); //Autodesk:F2C++ Array subscript usage: Replaced by below AvgTilt = sum_product_sub( state.dataSurface->Surface, &SurfaceData::Tilt, &SurfaceData::Area, state.dataSurface->ExtVentedCavity(Item).SurfPtrs) / @@ -7617,7 +7681,8 @@ namespace SurfaceGeometry { // find area weighted centroid. // ExtVentedCavity( Item ).Centroid.z = sum( Surface( ExtVentedCavity( Item ).SurfPtrs ).Centroid.z * Surface( // ExtVentedCavity( Item - //).SurfPtrs ).Area ) / sum( Surface( ExtVentedCavity( Item ).SurfPtrs ).Area ); //Autodesk:F2C++ Array subscript usage: Replaced by below + //).SurfPtrs ).Area ) / sum( Surface( ExtVentedCavity( Item ).SurfPtrs ).Area ); //Autodesk:F2C++ Array subscript usage: Replaced + // by below state.dataSurface->ExtVentedCavity(Item).Centroid.z = sum_product_sub(state.dataSurface->Surface, &SurfaceData::Centroid, &Vector::z, @@ -7940,11 +8005,11 @@ namespace SurfaceGeometry { cCurrentModuleObject, SurfLocalEnv.Name, state.dataIPShortCut->cAlphaFieldNames(2))); - ShowContinueError( - state, - format("{} entered value = \"{}\", no corresponding surface (ref BuildingSurface:Detailed) has been found in the input file.", - state.dataIPShortCut->cAlphaFieldNames(2), - state.dataIPShortCut->cAlphaArgs(2))); + ShowContinueError(state, + format("{} entered value = \"{}\", no corresponding surface (ref BuildingSurface:Detailed) has been " + "found in the input file.", + state.dataIPShortCut->cAlphaFieldNames(2), + state.dataIPShortCut->cAlphaArgs(2))); ErrorsFound = true; } else { SurfLocalEnv.SurfPtr = SurfNum; @@ -7981,11 +8046,11 @@ namespace SurfaceGeometry { cCurrentModuleObject, SurfLocalEnv.Name, state.dataIPShortCut->cAlphaFieldNames(4))); - ShowContinueError( - state, - format("{} entered value = \"{}\", no corresponding surrounding surfaces properties has been found in the input file.", - state.dataIPShortCut->cAlphaFieldNames(4), - state.dataIPShortCut->cAlphaArgs(4))); + ShowContinueError(state, + format("{} entered value = \"{}\", no corresponding surrounding surfaces properties has been found " + "in the input file.", + state.dataIPShortCut->cAlphaFieldNames(4), + state.dataIPShortCut->cAlphaArgs(4))); ErrorsFound = true; } else { SurfLocalEnv.SurroundingSurfsPtr = SurroundingSurfsNum; @@ -8049,7 +8114,6 @@ namespace SurfaceGeometry { if (SurfLocalEnv.SurfPtr == SurfLoop) { auto &surface = state.dataSurface->Surface(SurfLoop); if (SurfLocalEnv.OutdoorAirNodePtr != 0) { - surface.SurfHasLinkedOutAirNode = true; surface.SurfLinkedOutAirNode = SurfLocalEnv.OutdoorAirNodePtr; } if (SurfLocalEnv.ExtShadingSchedPtr != 0) { @@ -8153,8 +8217,8 @@ namespace SurfaceGeometry { SrdSurfsProp.GroundTempSchNum = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(3)); } - // The object requires at least one srd surface input, each surface requires a set of 3 fields (2 Alpha fields Name and Temp Sch Name - // and 1 Num fields View Factor) + // The object requires at least one srd surface input, each surface requires a set of 3 fields (2 Alpha fields Name and Temp + // Sch Name and 1 Num fields View Factor) if (NumAlpha < 5) { ShowSevereError(state, format("{} = \"{}\" is not defined correctly.", cCurrentModuleObject, SrdSurfsProp.Name)); ShowContinueError(state, "At lease one set of surrounding surface properties should be defined."); @@ -8820,6 +8884,12 @@ namespace SurfaceGeometry { state.dataHeatBalSurf->MaxSurfaceTempLimit, state.dataHeatBal->LowHConvLimit, state.dataHeatBal->HighHConvLimit); + if (state.dataHeatBal->doSpaceHeatBalanceSimulation || state.dataHeatBal->doSpaceHeatBalanceSizing) { + ShowSevereError( + state, + "MoisturePenetrationDepthConductionTransferFunction is not supported with ZoneAirHeatBalanceAlgorithm Space Heat Balance."); + ErrorsFound = true; + } } if (state.dataHeatBal->AnyCondFD) { state.dataHeatBal->AllCTF = false; @@ -8842,6 +8912,10 @@ namespace SurfaceGeometry { state.dataHeatBalSurf->MaxSurfaceTempLimit, state.dataHeatBal->LowHConvLimit, state.dataHeatBal->HighHConvLimit); + if (state.dataHeatBal->doSpaceHeatBalanceSimulation || state.dataHeatBal->doSpaceHeatBalanceSizing) { + ShowSevereError(state, "CombinedHeatAndMoistureFiniteElement is not supported with ZoneAirHeatBalanceAlgorithm Space Heat Balance."); + ErrorsFound = true; + } } if (state.dataHeatBal->AnyKiva) { state.dataHeatBal->AllCTF = false; @@ -9135,10 +9209,10 @@ namespace SurfaceGeometry { break; } else { if (state.dataGlobal->DisplayExtraWarnings) { - ShowContinueError( - state, - format("Cannot Drop Vertex [{}]; Number of Surface Sides at minimum. This surface is now a degenerate surface.", - curVertexIndex)); + ShowContinueError(state, + format("Cannot Drop Vertex [{}]; Number of Surface Sides at minimum. This surface is now a " + "degenerate surface.", + curVertexIndex)); } ++state.dataErrTracking->TotalDegenerateSurfaces; // mark degenerate surface? @@ -10067,7 +10141,8 @@ namespace SurfaceGeometry { void CheckWindowShadingControlSimilarForWindow(EnergyPlusData &state, bool &ErrorsFound) { - // For each window check if all window shading controls on list are the same except for name, schedule name, construction, and material + // For each window check if all window shading controls on list are the same except for name, schedule name, construction, and + // material for (auto &theSurf : state.dataSurface->Surface) { if (theSurf.HasShadeControl) { if (theSurf.windowShadingControlList.size() > 1) { @@ -11909,10 +11984,10 @@ namespace SurfaceGeometry { if (!isZoneEnclosed) { ++countNotFullyEnclosedZones; if (state.dataGlobal->DisplayExtraWarnings) { // report missing - ShowWarningError( - state, - "CalculateZoneVolume: The Zone=\"" + state.dataHeatBal->Zone(ZoneNum).Name + - "\" is not fully enclosed. To be fully enclosed, each edge of a surface must also be an edge on one other surface."); + ShowWarningError(state, + "CalculateZoneVolume: The Zone=\"" + state.dataHeatBal->Zone(ZoneNum).Name + + "\" is not fully enclosed. To be fully enclosed, each edge of a surface must also be an edge on one " + "other surface."); switch (volCalcMethod) { case ZoneVolumeCalcMethod::FloorAreaTimesHeight1: ShowContinueError(state, @@ -12029,6 +12104,15 @@ namespace SurfaceGeometry { thisSpace.Volume = thisZone.Volume * thisSpace.floorArea / thisZone.FloorArea; } } + Real64 totSpacesVolume = 0.0; + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + totSpacesVolume += state.dataHeatBal->space(spaceNum).Volume; + } + if (totSpacesVolume > 0.0) { + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + state.dataHeatBal->space(spaceNum).fracZoneVolume = state.dataHeatBal->space(spaceNum).Volume / totSpacesVolume; + } + } // else leave fractions at zero if (ShowZoneSurfaces) { if (ShowZoneSurfaceHeaders) { @@ -12084,10 +12168,10 @@ namespace SurfaceGeometry { ShowWarningError( state, "CalculateZoneVolume: 1 zone is not fully enclosed. For more details use: Output:Diagnostics,DisplayExtrawarnings; "); } else if (countNotFullyEnclosedZones > 1) { - ShowWarningError( - state, - format("CalculateZoneVolume: {} zones are not fully enclosed. For more details use: Output:Diagnostics,DisplayExtrawarnings; ", - countNotFullyEnclosedZones)); + ShowWarningError(state, + format("CalculateZoneVolume: {} zones are not fully enclosed. For more details use: " + "Output:Diagnostics,DisplayExtrawarnings; ", + countNotFullyEnclosedZones)); } } } @@ -12596,9 +12680,8 @@ namespace SurfaceGeometry { bool isPointOnLineBetweenPoints(DataVectorTypes::Vector start, DataVectorTypes::Vector end, DataVectorTypes::Vector test) { // J. Glazer - March 2017 - // The tolerance has to be low enough. Take for eg a plenum that has an edge that's 30meters long, you risk adding point from the floor to - // the roof, cf #7383 - // compute the shortest distance from the point to the line first to avoid false positive + // The tolerance has to be low enough. Take for eg a plenum that has an edge that's 30meters long, you risk adding point from the + // floor to the roof, cf #7383 compute the shortest distance from the point to the line first to avoid false positive Real64 tol = 0.0127; if (distanceFromPointToLine(start, end, test) < tol) { // distanceFromPointToLine always positive, it's calculated as norml_L2 return (std::abs((distance(start, end) - (distance(start, test) + distance(test, end)))) < tol); @@ -13565,8 +13648,10 @@ namespace SurfaceGeometry { // create a new construction with storm based on an old construction and storm and gap materials int createConstructionWithStorm(EnergyPlusData &state, int oldConstruction, std::string name, int stormMaterial, int gapMaterial) { - int newConstruct = UtilityRoutines::FindItemInList( - name, state.dataConstruction->Construct, state.dataHeatBal->TotConstructs); // Number of shaded storm window construction that is created + int newConstruct = + UtilityRoutines::FindItemInList(name, + state.dataConstruction->Construct, + state.dataHeatBal->TotConstructs); // Number of shaded storm window construction that is created if (newConstruct == 0) { state.dataHeatBal->TotConstructs = state.dataHeatBal->TotConstructs + 1; newConstruct = state.dataHeatBal->TotConstructs; @@ -14847,7 +14932,8 @@ namespace SurfaceGeometry { otherEnclosure.FloorArea += thisEnclosure.FloorArea; otherEnclosure.ExtWindowArea += thisEnclosure.ExtWindowArea; otherEnclosure.TotalSurfArea += thisEnclosure.TotalSurfArea; - // Move any enclosures beyond thisEnclosure down one slot - at this point all enclosures are named "Radiant Enclosure N" + // Move any enclosures beyond thisEnclosure down one slot - at this point all enclosures are named "Radiant + // Enclosure N" for (int enclNum = thisSideEnclosureNum; enclNum < enclosureNum; ++enclNum) { std::string saveName = Enclosures(enclNum).Name; Enclosures(enclNum) = Enclosures(enclNum + 1); diff --git a/src/EnergyPlus/SurfaceGeometry.hh b/src/EnergyPlus/SurfaceGeometry.hh index 33c2f07d607..3ee73fd2b57 100644 --- a/src/EnergyPlus/SurfaceGeometry.hh +++ b/src/EnergyPlus/SurfaceGeometry.hh @@ -88,7 +88,9 @@ namespace SurfaceGeometry { void GetSurfaceData(EnergyPlusData &state, bool &ErrorsFound); // If errors found in input - void CreateMissingSpaces(EnergyPlusData &state, bool &ErrorsFound); + void CreateMissingSpaces(EnergyPlusData &state, Array1D &Surfaces); + + void createSpaceSurfaceLists(EnergyPlusData &state, bool &ErrorsFound); void checkSubSurfAzTiltNorm(EnergyPlusData &state, SurfaceData &baseSurface, // Base surface data (in) diff --git a/src/EnergyPlus/SwimmingPool.cc b/src/EnergyPlus/SwimmingPool.cc index 9aa152e863b..104fce8c9de 100644 --- a/src/EnergyPlus/SwimmingPool.cc +++ b/src/EnergyPlus/SwimmingPool.cc @@ -80,6 +80,7 @@ #include #include #include +#include namespace EnergyPlus::SwimmingPool { @@ -535,7 +536,8 @@ void SwimmingPoolData::initialize(EnergyPlusData &state, bool const FirstHVACIte if (state.dataGlobal->BeginTimeStepFlag && FirstHVACIteration) { // This is the first pass through in a particular time step int ZoneNum = this->ZonePtr; - this->ZeroSourceSumHATsurf(ZoneNum) = SumHATsurf(state, ZoneNum); // Set this to figure what part of the load the radiant system meets + this->ZeroSourceSumHATsurf(ZoneNum) = + state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state); // Set this to figure what part of the load the radiant system meets int SurfNum = this->SurfacePtr; this->QPoolSrcAvg(SurfNum) = 0.0; // Initialize this variable to zero (pool parameters "off") this->HeatTransCoefsAvg(SurfNum) = 0.0; // Initialize this variable to zero (pool parameters "off") @@ -897,15 +899,17 @@ void SwimmingPoolData::calculate(EnergyPlusData &state) // initialize local variables int SurfNum = this->SurfacePtr; // surface number of floor that is the pool int ZoneNum = state.dataSurface->Surface(SurfNum).Zone; // index to zone array + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); // Convection coefficient calculation - Real64 HConvIn = 0.22 * std::pow(std::abs(this->PoolWaterTemp - state.dataHeatBalFanSys->MAT(ZoneNum)), 1.0 / 3.0) * - this->CurCoverConvFac; // convection coefficient for pool - calcSwimmingPoolEvap(state, EvapRate, SurfNum, state.dataHeatBalFanSys->MAT(ZoneNum), state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)); + Real64 HConvIn = + 0.22 * std::pow(std::abs(this->PoolWaterTemp - thisZoneHB.MAT), 1.0 / 3.0) * this->CurCoverConvFac; // convection coefficient for pool + calcSwimmingPoolEvap(state, EvapRate, SurfNum, thisZoneHB.MAT, thisZoneHB.ZoneAirHumRat); this->MakeUpWaterMassFlowRate = EvapRate; - Real64 EvapEnergyLossPerArea = - -EvapRate * Psychrometrics::PsyHfgAirFnWTdb(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum), state.dataHeatBalFanSys->MAT(ZoneNum)) / - state.dataSurface->Surface(SurfNum).Area; // energy effect of evaporation rate per unit area in W/m2 + Real64 EvapEnergyLossPerArea = -EvapRate * + Psychrometrics::PsyHfgAirFnWTdb(thisZoneHB.ZoneAirHumRat, + thisZoneHB.MAT) / + state.dataSurface->Surface(SurfNum).Area; // energy effect of evaporation rate per unit area in W/m2 this->EvapHeatLossRate = EvapEnergyLossPerArea * state.dataSurface->Surface(SurfNum).Area; // LW and SW radiation term modification: any "excess" radiation blocked by the cover gets convected // to the air directly and added to the zone air heat balance @@ -948,7 +952,7 @@ void SwimmingPoolData::calculate(EnergyPlusData &state) // We now have a flow rate so we can assemble the terms needed for the surface heat balance that is solved for the inside face temperature state.dataHeatBalFanSys->QPoolSurfNumerator(SurfNum) = - SWtotal + LWtotal + PeopleGain + EvapEnergyLossPerArea + HConvIn * state.dataHeatBalFanSys->MAT(ZoneNum) + + SWtotal + LWtotal + PeopleGain + EvapEnergyLossPerArea + HConvIn * thisZoneHB.MAT + (EvapRate * Tmuw + MassFlowRate * TLoopInletTemp + (this->WaterMass * TH22 / state.dataGlobal->TimeStepZoneSec)) * Cp / state.dataSurface->Surface(SurfNum).Area; state.dataHeatBalFanSys->PoolHeatTransCoefs(SurfNum) = @@ -956,8 +960,7 @@ void SwimmingPoolData::calculate(EnergyPlusData &state) // Finally take care of the latent and convective gains resulting from the pool state.dataHeatBalFanSys->SumConvPool(ZoneNum) += this->RadConvertToConvect; - state.dataHeatBalFanSys->SumLatentPool(ZoneNum) += - EvapRate * Psychrometrics::PsyHfgAirFnWTdb(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum), state.dataHeatBalFanSys->MAT(ZoneNum)); + state.dataHeatBalFanSys->SumLatentPool(ZoneNum) += EvapRate * Psychrometrics::PsyHfgAirFnWTdb(thisZoneHB.ZoneAirHumRat, thisZoneHB.MAT); } void SwimmingPoolData::calcSwimmingPoolEvap(EnergyPlusData &state, @@ -1102,49 +1105,6 @@ void UpdatePoolSourceValAvg(EnergyPlusData &state, bool &SwimmingPoolOn) // .TRU } } -Real64 SumHATsurf(EnergyPlusData &state, int const ZoneNum) // Zone number -{ - // FUNCTION INFORMATION: - // AUTHOR Peter Graham Ellis - // DATE WRITTEN July 2003 - - // PURPOSE OF THIS FUNCTION: - // This function calculates the zone sum of Hc*Area*Tsurf. It replaces the old SUMHAT. - // The SumHATsurf code below is also in the CalcZoneSums subroutine in ZoneTempPredictorCorrector and should be updated accordingly. - - Real64 SumHATsurf = 0.0; // Return value - - for (int SurfNum = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst; SurfNum <= state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast; ++SurfNum) { - Real64 Area = state.dataSurface->Surface(SurfNum).Area; // Effective surface area - - if (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window) { - if (state.dataSurface->SurfWinShadingFlag(SurfNum) == DataSurfaces::WinShadingType::IntShade || - state.dataSurface->SurfWinShadingFlag(SurfNum) == DataSurfaces::WinShadingType::IntBlind) { - // The area is the shade or blind are = sum of the glazing area and the divider area (which is zero if no divider) - Area += state.dataSurface->SurfWinDividerArea(SurfNum); - } - - if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) { - // Window frame contribution - SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinFrameArea(SurfNum) * - (1.0 + state.dataSurface->SurfWinProjCorrFrIn(SurfNum)) * state.dataSurface->SurfWinFrameTempIn(SurfNum); - } - - if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0 && - state.dataSurface->SurfWinShadingFlag(SurfNum) != DataSurfaces::WinShadingType::IntShade && - state.dataSurface->SurfWinShadingFlag(SurfNum) != DataSurfaces::WinShadingType::IntBlind) { - // Window divider contribution (only from shade or blind for window with divider and interior shade or blind) - SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinDividerArea(SurfNum) * - (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) * state.dataSurface->SurfWinDividerTempIn(SurfNum); - } - } - - SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * Area * state.dataHeatBalSurf->SurfTempInTmp(SurfNum); - } - - return SumHATsurf; -} - void ReportSwimmingPool(EnergyPlusData &state) { // SUBROUTINE INFORMATION: diff --git a/src/EnergyPlus/SwimmingPool.hh b/src/EnergyPlus/SwimmingPool.hh index 106a9def729..8f22500e7fa 100644 --- a/src/EnergyPlus/SwimmingPool.hh +++ b/src/EnergyPlus/SwimmingPool.hh @@ -194,8 +194,6 @@ namespace SwimmingPool { void UpdatePoolSourceValAvg(EnergyPlusData &state, bool &SwimmingPoolOn); // .TRUE. if the swimming pool has "run" this zone time step - Real64 SumHATsurf(EnergyPlusData &state, int ZoneNum); // Zone number - void ReportSwimmingPool(EnergyPlusData &state); Real64 MakeUpWaterVolFlowFunct(Real64 MakeUpWaterMassFlowRate, Real64 Density); diff --git a/src/EnergyPlus/SystemAvailabilityManager.cc b/src/EnergyPlus/SystemAvailabilityManager.cc index 5f9d4c26f29..30e930f9094 100644 --- a/src/EnergyPlus/SystemAvailabilityManager.cc +++ b/src/EnergyPlus/SystemAvailabilityManager.cc @@ -80,6 +80,7 @@ #include #include #include +#include namespace EnergyPlus { @@ -4662,6 +4663,7 @@ namespace SystemAvailabilityManager { } int ZoneNum = hybridVentMgr.ControlledZoneNum; + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); if (!KeepStatus) hybridVentMgr.VentilationCtrl = HybridVentCtrl_NoAction; TempExt = state.dataHeatBal->Zone(ZoneNum).OutDryBulbTemp; WindExt = state.dataHeatBal->Zone(ZoneNum).WindSpeed; @@ -4687,7 +4689,7 @@ namespace SystemAvailabilityManager { // Enthalpy control } break; case HybridVentMode_Enth: { - ZoneAirEnthalpy = PsyHFnTdbW(state.dataHeatBalFanSys->MAT(ZoneNum), state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)); + ZoneAirEnthalpy = PsyHFnTdbW(thisZoneHB.MAT, thisZoneHB.ZoneAirHumRat); if (state.dataEnvrn->OutEnthalpy >= hybridVentMgr.MinOutdoorEnth && state.dataEnvrn->OutEnthalpy <= hybridVentMgr.MaxOutdoorEnth) { hybridVentMgr.VentilationCtrl = HybridVentCtrl_Open; } else { @@ -4728,7 +4730,7 @@ namespace SystemAvailabilityManager { } break; case HybridVentMode_OperT80: { if (state.dataThermalComforts->runningAverageASH >= 10.0 && state.dataThermalComforts->runningAverageASH <= 33.5) { - hybridVentMgr.OperativeTemp = 0.5 * (state.dataHeatBalFanSys->MAT(ZoneNum) + state.dataHeatBal->ZoneMRT(ZoneNum)); + hybridVentMgr.OperativeTemp = 0.5 * (thisZoneHB.MAT + state.dataHeatBal->ZoneMRT(ZoneNum)); minAdaTem = 0.31 * state.dataThermalComforts->runningAverageASH + 14.3; maxAdaTem = 0.31 * state.dataThermalComforts->runningAverageASH + 21.3; hybridVentMgr.minAdaTem = minAdaTem; @@ -4745,7 +4747,7 @@ namespace SystemAvailabilityManager { } break; case HybridVentMode_OperT90: { if (state.dataThermalComforts->runningAverageASH >= 10.0 && state.dataThermalComforts->runningAverageASH <= 33.5) { - hybridVentMgr.OperativeTemp = 0.5 * (state.dataHeatBalFanSys->MAT(ZoneNum) + state.dataHeatBal->ZoneMRT(ZoneNum)); + hybridVentMgr.OperativeTemp = 0.5 * (thisZoneHB.MAT + state.dataHeatBal->ZoneMRT(ZoneNum)); minAdaTem = 0.31 * state.dataThermalComforts->runningAverageASH + 15.3; maxAdaTem = 0.31 * state.dataThermalComforts->runningAverageASH + 20.3; hybridVentMgr.minAdaTem = minAdaTem; @@ -4813,13 +4815,13 @@ namespace SystemAvailabilityManager { switch (state.dataHeatBalFanSys->TempControlType(ZoneNum)) { case DataHVACGlobals::ThermostatType::SingleHeating: { - if (state.dataHeatBalFanSys->MAT(ZoneNum) < state.dataHeatBalFanSys->TempZoneThermostatSetPoint(ZoneNum)) { + if (thisZoneHB.MAT < state.dataHeatBalFanSys->TempZoneThermostatSetPoint(ZoneNum)) { hybridVentMgr.VentilationCtrl = HybridVentCtrl_Close; } } break; case DataHVACGlobals::ThermostatType::SingleCooling: { - if (state.dataHeatBalFanSys->MAT(ZoneNum) > state.dataHeatBalFanSys->TempZoneThermostatSetPoint(ZoneNum)) { + if (thisZoneHB.MAT > state.dataHeatBalFanSys->TempZoneThermostatSetPoint(ZoneNum)) { hybridVentMgr.VentilationCtrl = HybridVentCtrl_Close; } @@ -4845,8 +4847,8 @@ namespace SystemAvailabilityManager { } break; case DataHVACGlobals::ThermostatType::DualSetPointWithDeadBand: { - if ((state.dataHeatBalFanSys->MAT(ZoneNum) < state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ZoneNum)) || - (state.dataHeatBalFanSys->MAT(ZoneNum) > state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ZoneNum))) { + if ((thisZoneHB.MAT < state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ZoneNum)) || + (thisZoneHB.MAT > state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ZoneNum))) { hybridVentMgr.VentilationCtrl = HybridVentCtrl_Close; } @@ -4858,12 +4860,8 @@ namespace SystemAvailabilityManager { // Dew point control mode if (hybridVentMgr.ControlMode == HybridVentMode_DewPoint) { - ZoneAirRH = PsyRhFnTdbWPb(state, - state.dataHeatBalFanSys->MAT(ZoneNum), - state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum), - state.dataEnvrn->OutBaroPress) * - 100.0; - ZoneAirDewPoint = PsyTdpFnWPb(state, state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum), state.dataEnvrn->OutBaroPress); + ZoneAirRH = PsyRhFnTdbWPb(state, thisZoneHB.MAT, thisZoneHB.ZoneAirHumRat, state.dataEnvrn->OutBaroPress) * 100.0; + ZoneAirDewPoint = PsyTdpFnWPb(state, thisZoneHB.ZoneAirHumRat, state.dataEnvrn->OutBaroPress); if (state.dataZoneCtrls->NumHumidityControlZones == 0) { ++hybridVentMgr.DewPointNoRHErrCount; if (hybridVentMgr.DewPointNoRHErrCount < 2) { @@ -4891,14 +4889,11 @@ namespace SystemAvailabilityManager { ZoneRHDehumidifyingSetPoint = GetCurrentScheduleValue(state, state.dataZoneCtrls->HumidityControlZone(HStatZoneNum).DehumidifyingSchedIndex); if (ZoneAirRH > ZoneRHDehumidifyingSetPoint) { // Need dehumidification - WSetPoint = PsyWFnTdbRhPb(state, - state.dataHeatBalFanSys->MAT(ZoneNum), - (ZoneRHDehumidifyingSetPoint / 100.0), - state.dataEnvrn->OutBaroPress); + WSetPoint = + PsyWFnTdbRhPb(state, thisZoneHB.MAT, (ZoneRHDehumidifyingSetPoint / 100.0), state.dataEnvrn->OutBaroPress); if (WSetPoint < state.dataEnvrn->OutHumRat) hybridVentMgr.VentilationCtrl = HybridVentCtrl_Close; } else if (ZoneAirRH < ZoneRHHumidifyingSetPoint) { // Need humidification - WSetPoint = PsyWFnTdbRhPb( - state, state.dataHeatBalFanSys->MAT(ZoneNum), (ZoneRHHumidifyingSetPoint / 100.0), state.dataEnvrn->OutBaroPress); + WSetPoint = PsyWFnTdbRhPb(state, thisZoneHB.MAT, (ZoneRHHumidifyingSetPoint / 100.0), state.dataEnvrn->OutBaroPress); if (WSetPoint > state.dataEnvrn->OutHumRat) hybridVentMgr.VentilationCtrl = HybridVentCtrl_Close; } else { hybridVentMgr.VentilationCtrl = HybridVentCtrl_Close; diff --git a/src/EnergyPlus/SystemReports.cc b/src/EnergyPlus/SystemReports.cc index 3145b7ef09f..a1e24cf3cfc 100644 --- a/src/EnergyPlus/SystemReports.cc +++ b/src/EnergyPlus/SystemReports.cc @@ -65,7 +65,6 @@ #include #include #include -#include #include #include #include @@ -86,6 +85,7 @@ #include #include #include +#include namespace EnergyPlus::SystemReports { @@ -4516,8 +4516,11 @@ void ReportVentilationLoads(EnergyPlusData &state) } // determine volumetric values from mass flow using current air density for zone (adjusted for elevation) - Real64 currentZoneAirDensity = Psychrometrics::PsyRhoAirFnPbTdbW( - state, state.dataEnvrn->OutBaroPress, state.dataHeatBalFanSys->MAT(CtrlZoneNum), state.dataHeatBalFanSys->ZoneAirHumRatAvg(CtrlZoneNum)); + Real64 currentZoneAirDensity = + Psychrometrics::PsyRhoAirFnPbTdbW(state, + state.dataEnvrn->OutBaroPress, + state.dataZoneTempPredictorCorrector->zoneHeatBalance(CtrlZoneNum).MAT, + state.dataZoneTempPredictorCorrector->zoneHeatBalance(CtrlZoneNum).ZoneAirHumRatAvg); if (currentZoneAirDensity > 0.0) thisZoneVentRepVars.OAVolFlowCrntRho = thisZoneVentRepVars.OAMassFlow / currentZoneAirDensity; thisZoneVentRepVars.OAVolCrntRho = thisZoneVentRepVars.OAVolFlowCrntRho * TimeStepSys * DataGlobalConstants::SecInHour; if (ZoneVolume > 0.0) thisZoneVentRepVars.MechACH = (thisZoneVentRepVars.OAVolCrntRho / TimeStepSys) / ZoneVolume; diff --git a/src/EnergyPlus/ThermalChimney.cc b/src/EnergyPlus/ThermalChimney.cc index 1f51a3811a6..e496e4d0d7a 100644 --- a/src/EnergyPlus/ThermalChimney.cc +++ b/src/EnergyPlus/ThermalChimney.cc @@ -55,7 +55,6 @@ #include #include #include -#include #include #include #include @@ -68,6 +67,7 @@ #include #include #include +#include namespace EnergyPlus { @@ -97,7 +97,6 @@ namespace ThermalChimney { // Using/Aliasing using namespace DataEnvironment; - using namespace DataHeatBalFanSys; using namespace DataHeatBalance; using namespace DataSurfaces; using namespace DataHeatBalSurface; @@ -670,9 +669,6 @@ namespace ThermalChimney { // SUBROUTINE LOCAL VARIABLE DECLARATIONS: // Real local vaiables - int Loop; // DO loop counter - int SurfNum; // DO loop counter for surfaces - int ZoneNum; // DO loop counter for zones int TCZoneNumCounter; int TCZoneNum; Real64 minorW; // width of enclosure (narrow dimension) @@ -710,45 +706,49 @@ namespace ThermalChimney { Array1D EquaConst(NTC); // Constants in Linear Algebraic Equation for FINITE DIFFERENCE Array1D ThermChimSubTemp(NTC); // Air temperature of each thermal chimney air channel subregion - for (Loop = 1; Loop <= state.dataThermalChimneys->TotThermalChimney; ++Loop) { + for (int Loop = 1; Loop <= state.dataThermalChimneys->TotThermalChimney; ++Loop) { - ZoneNum = state.dataThermalChimneys->ThermalChimneySys(Loop).RealZonePtr; + int ZoneNum = state.dataThermalChimneys->ThermalChimneySys(Loop).RealZonePtr; + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); // start off with first surface in zone widths - majorW = state.dataSurface->Surface(state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst).Width; + int firstSpaceHTSurfaceFirst = state.dataHeatBal->space(state.dataHeatBal->Zone(ZoneNum).spaceIndexes(1)).HTSurfaceFirst; + majorW = state.dataSurface->Surface(firstSpaceHTSurfaceFirst).Width; minorW = majorW; TempmajorW = 0.0; TemporaryWallSurfTemp = -10000.0; // determine major width and minor width - for (SurfNum = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst + 1; SurfNum <= state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast; - ++SurfNum) { - if (state.dataSurface->Surface(SurfNum).Class != SurfaceClass::Wall) continue; + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { + if (state.dataSurface->Surface(SurfNum).Class != SurfaceClass::Wall) continue; - if (state.dataSurface->Surface(SurfNum).Width > majorW) { - majorW = state.dataSurface->Surface(SurfNum).Width; - } + if (state.dataSurface->Surface(SurfNum).Width > majorW) { + majorW = state.dataSurface->Surface(SurfNum).Width; + } - if (state.dataSurface->Surface(SurfNum).Width < minorW) { - minorW = state.dataSurface->Surface(SurfNum).Width; + if (state.dataSurface->Surface(SurfNum).Width < minorW) { + minorW = state.dataSurface->Surface(SurfNum).Width; + } } - } - for (SurfNum = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst; SurfNum <= state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast; ++SurfNum) { - if (state.dataSurface->Surface(SurfNum).Width == majorW) { - if (state.dataHeatBalSurf->SurfTempIn(SurfNum) > TemporaryWallSurfTemp) { - TemporaryWallSurfTemp = state.dataHeatBalSurf->SurfTempIn(SurfNum); - ConvTransCoeffWallFluid = state.dataHeatBalSurf->SurfHConvInt(SurfNum); - SurfTempAbsorberWall = state.dataHeatBalSurf->SurfTempIn(SurfNum) + DataGlobalConstants::KelvinConv; + for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { + if (state.dataSurface->Surface(SurfNum).Width == majorW) { + if (state.dataHeatBalSurf->SurfTempIn(SurfNum) > TemporaryWallSurfTemp) { + TemporaryWallSurfTemp = state.dataHeatBalSurf->SurfTempIn(SurfNum); + ConvTransCoeffWallFluid = state.dataHeatBalSurf->SurfHConvInt(SurfNum); + SurfTempAbsorberWall = state.dataHeatBalSurf->SurfTempIn(SurfNum) + DataGlobalConstants::KelvinConv; + } } } - } - for (SurfNum = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst; SurfNum <= state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast; ++SurfNum) { - if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Window) { - if (state.dataSurface->Surface(SurfNum).Width > TempmajorW) { - TempmajorW = state.dataSurface->Surface(SurfNum).Width; - ConvTransCoeffGlassFluid = state.dataHeatBalSurf->SurfHConvInt(SurfNum); - SurfTempGlassCover = state.dataHeatBalSurf->SurfTempIn(SurfNum) + DataGlobalConstants::KelvinConv; + for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { + if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Window) { + if (state.dataSurface->Surface(SurfNum).Width > TempmajorW) { + TempmajorW = state.dataSurface->Surface(SurfNum).Width; + ConvTransCoeffGlassFluid = state.dataHeatBalSurf->SurfHConvInt(SurfNum); + SurfTempGlassCover = state.dataHeatBalSurf->SurfTempIn(SurfNum) + DataGlobalConstants::KelvinConv; + } } } } @@ -758,9 +758,8 @@ namespace ThermalChimney { AbsorberWallWidthTC = state.dataThermalChimneys->ThermalChimneySys(Loop).AbsorberWallWidth; } - AirDensityThermalChim = PsyRhoAirFnPbTdbW( - state, state.dataEnvrn->OutBaroPress, state.dataHeatBalFanSys->MAT(ZoneNum), state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)); - AirSpecHeatThermalChim = PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)); + AirDensityThermalChim = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, thisZoneHB.MAT, thisZoneHB.ZoneAirHumRat); + AirSpecHeatThermalChim = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat); AirOutletCrossAreaTC = state.dataThermalChimneys->ThermalChimneySys(Loop).AirOutletCrossArea; DischargeCoeffTC = state.dataThermalChimneys->ThermalChimneySys(Loop).DischargeCoeff; @@ -773,7 +772,7 @@ namespace ThermalChimney { for (TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) { TCZoneNumCounter = state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum); RoomAirTemp += state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum) * - state.dataHeatBalFanSys->MAT(TCZoneNumCounter); + state.dataZoneTempPredictorCorrector->zoneHeatBalance(TCZoneNumCounter).MAT; } RoomAirTemp += DataGlobalConstants::KelvinConv; @@ -781,11 +780,12 @@ namespace ThermalChimney { Process2 = 0.0; for (TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) { TCZoneNumCounter = state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum); - Process1 += PsyHFnTdbW(state.dataHeatBalFanSys->MAT(TCZoneNumCounter), state.dataHeatBalFanSys->ZoneAirHumRat(TCZoneNumCounter)) * + auto &thisTCZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(TCZoneNumCounter); + Process1 += PsyHFnTdbW(thisTCZoneHB.MAT, thisTCZoneHB.ZoneAirHumRat) * state.dataThermalChimneys->ThermalChimneySys(Loop).DistanceThermChimInlet(TCZoneNum) * state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum); Process2 += state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum) * - PsyHFnTdbW(state.dataHeatBalFanSys->MAT(TCZoneNumCounter), state.dataHeatBalFanSys->ZoneAirHumRat(TCZoneNumCounter)); + PsyHFnTdbW(state.dataZoneTempPredictorCorrector->zoneHeatBalance(TCZoneNumCounter).MAT, thisTCZoneHB.ZoneAirHumRat); } OverallThermalChimLength = Process1 / Process2; @@ -883,28 +883,27 @@ namespace ThermalChimney { // Now assignment of the overall mass flow rate into each zone for (TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) { TCZoneNumCounter = state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum); + auto &thisTCZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(TCZoneNumCounter); AirDensity = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, - state.dataHeatBalFanSys->MAT(TCZoneNumCounter), - state.dataHeatBalFanSys->ZoneAirHumRat(TCZoneNumCounter)); - CpAir = PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(TCZoneNumCounter)); - state.dataHeatBalFanSys->MCPThermChim(TCZoneNumCounter) = + state.dataZoneTempPredictorCorrector->zoneHeatBalance(TCZoneNumCounter).MAT, + thisTCZoneHB.ZoneAirHumRat); + CpAir = PsyCpAirFnW(thisTCZoneHB.ZoneAirHumRat); + thisTCZoneHB.MCPThermChim = TCVolumeAirFlowRate * AirDensity * CpAir * state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum); - if (state.dataHeatBalFanSys->MCPThermChim(TCZoneNumCounter) <= 0.0) { - state.dataHeatBalFanSys->MCPThermChim(TCZoneNumCounter) = 0.0; + if (thisTCZoneHB.MCPThermChim <= 0.0) { + thisTCZoneHB.MCPThermChim = 0.0; } - state.dataHeatBalFanSys->ThermChimAMFL(TCZoneNumCounter) = state.dataHeatBalFanSys->MCPThermChim(TCZoneNumCounter) / CpAir; - state.dataHeatBalFanSys->MCPTThermChim(TCZoneNumCounter) = - state.dataHeatBalFanSys->MCPThermChim(TCZoneNumCounter) * state.dataHeatBal->Zone(TCZoneNumCounter).OutDryBulbTemp; + thisTCZoneHB.ThermChimAMFL = thisTCZoneHB.MCPThermChim / CpAir; + thisTCZoneHB.MCPTThermChim = thisTCZoneHB.MCPThermChim * state.dataHeatBal->Zone(TCZoneNumCounter).OutDryBulbTemp; } - state.dataHeatBalFanSys->MCPThermChim(ZoneNum) = TCVolumeAirFlowRate * AirDensity * CpAir; - if (state.dataHeatBalFanSys->MCPThermChim(ZoneNum) <= 0.0) { - state.dataHeatBalFanSys->MCPThermChim(ZoneNum) = 0.0; + thisZoneHB.MCPThermChim = TCVolumeAirFlowRate * AirDensity * CpAir; + if (thisZoneHB.MCPThermChim <= 0.0) { + thisZoneHB.MCPThermChim = 0.0; } - state.dataHeatBalFanSys->ThermChimAMFL(ZoneNum) = state.dataHeatBalFanSys->MCPThermChim(ZoneNum) / CpAir; - state.dataHeatBalFanSys->MCPTThermChim(ZoneNum) = - state.dataHeatBalFanSys->MCPThermChim(ZoneNum) * state.dataHeatBal->Zone(ZoneNum).OutDryBulbTemp; + thisZoneHB.ThermChimAMFL = thisZoneHB.MCPThermChim / CpAir; + thisZoneHB.MCPTThermChim = thisZoneHB.MCPThermChim * state.dataHeatBal->Zone(ZoneNum).OutDryBulbTemp; state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCVolumeFlow = TCVolumeAirFlowRate; state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCMassFlow = TCMassAirFlowRate; @@ -918,17 +917,19 @@ namespace ThermalChimney { if (GetCurrentScheduleValue(state, state.dataThermalChimneys->ThermalChimneySys(Loop).SchedPtr) <= 0.0) { for (TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) { TCZoneNumCounter = state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum); - state.dataHeatBalFanSys->MCPThermChim(TCZoneNumCounter) = 0.0; - state.dataHeatBalFanSys->ThermChimAMFL(TCZoneNumCounter) = 0.0; - state.dataHeatBalFanSys->MCPTThermChim(TCZoneNumCounter) = 0.0; + auto &thisTCZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(TCZoneNumCounter); + thisTCZoneHB.MCPThermChim = 0.0; + thisTCZoneHB.ThermChimAMFL = 0.0; + thisTCZoneHB.MCPTThermChim = 0.0; } - state.dataHeatBalFanSys->MCPThermChim(ZoneNum) = 0.0; - state.dataHeatBalFanSys->ThermChimAMFL(ZoneNum) = 0.0; - state.dataHeatBalFanSys->MCPTThermChim(ZoneNum) = 0.0; + thisZoneHB.MCPThermChim = 0.0; + thisZoneHB.ThermChimAMFL = 0.0; + thisZoneHB.MCPTThermChim = 0.0; state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCVolumeFlow = 0.0; state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCVolumeFlowStd = 0.0; state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCMassFlow = 0.0; - state.dataThermalChimneys->ThermalChimneyReport(Loop).OutletAirTempThermalChim = state.dataHeatBalFanSys->MAT(ZoneNum); + state.dataThermalChimneys->ThermalChimneyReport(Loop).OutletAirTempThermalChim = + state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; } } // DO Loop=1, TotThermalChimney @@ -956,31 +957,30 @@ namespace ThermalChimney { TSMult = TimeStepSys * DataGlobalConstants::SecInHour; for (ZoneLoop = 1; ZoneLoop <= state.dataGlobal->NumOfZones; ++ZoneLoop) { // Start of zone loads report variable update loop ... + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneLoop); // Break the infiltration load into heat gain and loss components. AirDensity = PsyRhoAirFnPbTdbW( - state, state.dataEnvrn->OutBaroPress, state.dataHeatBalFanSys->MAT(ZoneLoop), state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop)); - CpAir = PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneLoop)); - state.dataThermalChimneys->ZnRptThermChim(ZoneLoop).ThermalChimneyVolume = - (state.dataHeatBalFanSys->MCPThermChim(ZoneLoop) / CpAir / AirDensity) * TSMult; - state.dataThermalChimneys->ZnRptThermChim(ZoneLoop).ThermalChimneyMass = - (state.dataHeatBalFanSys->MCPThermChim(ZoneLoop) / CpAir) * TSMult; + state, state.dataEnvrn->OutBaroPress, state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneLoop).MAT, thisZoneHB.ZoneAirHumRat); + CpAir = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat); + state.dataThermalChimneys->ZnRptThermChim(ZoneLoop).ThermalChimneyVolume = (thisZoneHB.MCPThermChim / CpAir / AirDensity) * TSMult; + state.dataThermalChimneys->ZnRptThermChim(ZoneLoop).ThermalChimneyMass = (thisZoneHB.MCPThermChim / CpAir) * TSMult; state.dataThermalChimneys->ZnRptThermChim(ZoneLoop).ThermalChimneyHeatLoss = 0.0; state.dataThermalChimneys->ZnRptThermChim(ZoneLoop).ThermalChimneyHeatGain = 0.0; - if (state.dataHeatBalFanSys->ZT(ZoneLoop) > state.dataHeatBal->Zone(ZoneLoop).OutDryBulbTemp) { + if (state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneLoop).ZT > state.dataHeatBal->Zone(ZoneLoop).OutDryBulbTemp) { state.dataThermalChimneys->ZnRptThermChim(ZoneLoop).ThermalChimneyHeatLoss = - state.dataHeatBalFanSys->MCPThermChim(ZoneLoop) * - (state.dataHeatBalFanSys->ZT(ZoneLoop) - state.dataHeatBal->Zone(ZoneLoop).OutDryBulbTemp) * TSMult; + thisZoneHB.MCPThermChim * + (state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneLoop).ZT - state.dataHeatBal->Zone(ZoneLoop).OutDryBulbTemp) * TSMult; state.dataThermalChimneys->ZnRptThermChim(ZoneLoop).ThermalChimneyHeatGain = 0.0; - } else if (state.dataHeatBalFanSys->ZT(ZoneLoop) <= state.dataHeatBal->Zone(ZoneLoop).OutDryBulbTemp) { + } else if (state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneLoop).ZT <= state.dataHeatBal->Zone(ZoneLoop).OutDryBulbTemp) { state.dataThermalChimneys->ZnRptThermChim(ZoneLoop).ThermalChimneyHeatGain = - state.dataHeatBalFanSys->MCPThermChim(ZoneLoop) * - (state.dataHeatBal->Zone(ZoneLoop).OutDryBulbTemp - state.dataHeatBalFanSys->ZT(ZoneLoop)) * TSMult; + thisZoneHB.MCPThermChim * + (state.dataHeatBal->Zone(ZoneLoop).OutDryBulbTemp - state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneLoop).ZT) * TSMult; state.dataThermalChimneys->ZnRptThermChim(ZoneLoop).ThermalChimneyHeatLoss = 0.0; } @@ -989,39 +989,13 @@ namespace ThermalChimney { void GaussElimination(Array2A EquaCoef, Array1D &EquaConst, Array1D &ThermChimSubTemp, int const NTC) { - // SUBROUTINE INFORMATION: - // PURPOSE OF THIS SUBROUTINE: // This subroutine sovles linear algebraic equations using Gauss Elimination Method. - // METHODOLOGY EMPLOYED: - // na - - // REFERENCES: - // na - - // USE STATEMENTS: - - // Argument array dimensioning EquaCoef.dim(NTC, NTC); EP_SIZE_CHECK(EquaConst, NTC); EP_SIZE_CHECK(ThermChimSubTemp, NTC); - // Locals - // SUBROUTINE ARGUMENT DEFINITIONS: - // na - - // SUBROUTINE PARAMETER DEFINITIONS: - // na - - // INTERFACE BLOCK SPECIFICATIONS - // na - - // DERIVED TYPE DEFINITIONS - // na - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - Array1D tempor(NTC); Real64 tempb; Real64 TCvalue; diff --git a/src/EnergyPlus/ThermalComfort.cc b/src/EnergyPlus/ThermalComfort.cc index 5ce62805587..e71f0cfb76e 100644 --- a/src/EnergyPlus/ThermalComfort.cc +++ b/src/EnergyPlus/ThermalComfort.cc @@ -530,43 +530,38 @@ namespace ThermalComfort { if ((!state.dataHeatBal->People(state.dataThermalComforts->PeopleNum).Fanger) && (!present(PNum))) continue; state.dataThermalComforts->ZoneNum = state.dataHeatBal->People(state.dataThermalComforts->PeopleNum).ZonePtr; - if (state.dataRoomAirMod->IsZoneDV(state.dataThermalComforts->ZoneNum) || - state.dataRoomAirMod->IsZoneUI(state.dataThermalComforts->ZoneNum)) { - state.dataThermalComforts->AirTemp = state.dataRoomAirMod->TCMF(state.dataThermalComforts->ZoneNum); // PH 3/7/04 - // UCSD-CV - } else if (state.dataRoomAirMod->IsZoneCV(state.dataThermalComforts->ZoneNum)) { - if (state.dataRoomAirMod->ZoneUCSDCV(state.dataThermalComforts->ZoneNum).VforComfort == DataRoomAirModel::Comfort::Jet) { - state.dataThermalComforts->AirTemp = state.dataRoomAirMod->ZTJET(state.dataThermalComforts->ZoneNum); - } else if (state.dataRoomAirMod->ZoneUCSDCV(state.dataThermalComforts->ZoneNum).VforComfort == - DataRoomAirModel::Comfort::Recirculation) { - state.dataThermalComforts->AirTemp = state.dataRoomAirMod->ZTJET(state.dataThermalComforts->ZoneNum); - } else { - // Thermal comfort control uses Tset to determine PMV setpoint value, otherwise use zone temp - if (present(PNum)) { - state.dataThermalComforts->AirTemp = Tset; - } else { - state.dataThermalComforts->AirTemp = state.dataHeatBalFanSys->ZTAVComf(state.dataThermalComforts->ZoneNum); - } - } + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataThermalComforts->ZoneNum); + if (present(PNum)) { + state.dataThermalComforts->AirTemp = Tset; } else { - if (present(PNum)) { - state.dataThermalComforts->AirTemp = Tset; - } else { - state.dataThermalComforts->AirTemp = state.dataHeatBalFanSys->ZTAVComf(state.dataThermalComforts->ZoneNum); + state.dataThermalComforts->AirTemp = thisZoneHB.ZTAVComf; + } + if (state.dataRoomAirMod->anyNonMixingRoomAirModel) { + state.dataThermalComforts->ZoneNum = state.dataHeatBal->People(state.dataThermalComforts->PeopleNum).ZonePtr; + if (state.dataRoomAirMod->IsZoneDV(state.dataThermalComforts->ZoneNum) || + state.dataRoomAirMod->IsZoneUI(state.dataThermalComforts->ZoneNum)) { + state.dataThermalComforts->AirTemp = state.dataRoomAirMod->TCMF(state.dataThermalComforts->ZoneNum); // PH 3/7/04 + // UCSD-CV + } else if (state.dataRoomAirMod->IsZoneCV(state.dataThermalComforts->ZoneNum)) { + if (state.dataRoomAirMod->ZoneUCSDCV(state.dataThermalComforts->ZoneNum).VforComfort == DataRoomAirModel::Comfort::Jet) { + state.dataThermalComforts->AirTemp = state.dataRoomAirMod->ZTJET(state.dataThermalComforts->ZoneNum); + } else if (state.dataRoomAirMod->ZoneUCSDCV(state.dataThermalComforts->ZoneNum).VforComfort == + DataRoomAirModel::Comfort::Recirculation) { + state.dataThermalComforts->AirTemp = state.dataRoomAirMod->ZTJET(state.dataThermalComforts->ZoneNum); + } } } state.dataThermalComforts->RadTemp = CalcRadTemp(state, state.dataThermalComforts->PeopleNum); // Use mean air temp for calculating RH when thermal comfort control is used if (present(PNum)) { - state.dataThermalComforts->RelHum = PsyRhFnTdbWPb(state, - state.dataHeatBalFanSys->MAT(state.dataThermalComforts->ZoneNum), - state.dataHeatBalFanSys->ZoneAirHumRatAvgComf(state.dataThermalComforts->ZoneNum), - state.dataEnvrn->OutBaroPress); + state.dataThermalComforts->RelHum = + PsyRhFnTdbWPb(state, + state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataThermalComforts->ZoneNum).MAT, + thisZoneHB.ZoneAirHumRatAvgComf, + state.dataEnvrn->OutBaroPress); } else { - state.dataThermalComforts->RelHum = PsyRhFnTdbWPb(state, - state.dataThermalComforts->AirTemp, - state.dataHeatBalFanSys->ZoneAirHumRatAvgComf(state.dataThermalComforts->ZoneNum), - state.dataEnvrn->OutBaroPress); + state.dataThermalComforts->RelHum = + PsyRhFnTdbWPb(state, state.dataThermalComforts->AirTemp, thisZoneHB.ZoneAirHumRatAvgComf, state.dataEnvrn->OutBaroPress); } state.dataHeatBal->People(state.dataThermalComforts->PeopleNum).TemperatureInZone = state.dataThermalComforts->AirTemp; state.dataHeatBal->People(state.dataThermalComforts->PeopleNum).RelativeHumidityInZone = state.dataThermalComforts->RelHum * 100.0; @@ -623,7 +618,7 @@ namespace ThermalComfort { "PEOPLE=\"" + state.dataHeatBal->People(state.dataThermalComforts->PeopleNum).Name + "\", Incorrect Clothing Type"); } - if (state.dataRoomAirMod->IsZoneCV(state.dataThermalComforts->ZoneNum)) { + if (state.dataRoomAirMod->anyNonMixingRoomAirModel && state.dataRoomAirMod->IsZoneCV(state.dataThermalComforts->ZoneNum)) { if (state.dataRoomAirMod->ZoneUCSDCV(state.dataThermalComforts->ZoneNum).VforComfort == DataRoomAirModel::Comfort::Jet) { state.dataThermalComforts->AirVel = state.dataRoomAirMod->Ujet(state.dataThermalComforts->ZoneNum); } else if (state.dataRoomAirMod->ZoneUCSDCV(state.dataThermalComforts->ZoneNum).VforComfort == @@ -830,20 +825,20 @@ namespace ThermalComfort { void GetThermalComfortInputsASHRAE(EnergyPlusData &state) { state.dataThermalComforts->ZoneNum = state.dataHeatBal->People(state.dataThermalComforts->PeopleNum).ZonePtr; + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataThermalComforts->ZoneNum); // (var TA) - if (state.dataRoomAirMod->IsZoneDV(state.dataThermalComforts->ZoneNum) || - state.dataRoomAirMod->IsZoneUI(state.dataThermalComforts->ZoneNum)) { - state.dataThermalComforts->AirTemp = state.dataRoomAirMod->TCMF(state.dataThermalComforts->ZoneNum); // PH 3/7/04 - } else { - state.dataThermalComforts->AirTemp = state.dataHeatBalFanSys->ZTAVComf(state.dataThermalComforts->ZoneNum); + state.dataThermalComforts->AirTemp = thisZoneHB.ZTAVComf; + if (state.dataRoomAirMod->anyNonMixingRoomAirModel) { + if (state.dataRoomAirMod->IsZoneDV(state.dataThermalComforts->ZoneNum) || + state.dataRoomAirMod->IsZoneUI(state.dataThermalComforts->ZoneNum)) { + state.dataThermalComforts->AirTemp = state.dataRoomAirMod->TCMF(state.dataThermalComforts->ZoneNum); // PH 3/7/04 + } } // (var TR) state.dataThermalComforts->RadTemp = CalcRadTemp(state, state.dataThermalComforts->PeopleNum); // (var RH) - state.dataThermalComforts->RelHum = PsyRhFnTdbWPb(state, - state.dataThermalComforts->AirTemp, - state.dataHeatBalFanSys->ZoneAirHumRatAvgComf(state.dataThermalComforts->ZoneNum), - state.dataEnvrn->OutBaroPress); + state.dataThermalComforts->RelHum = + PsyRhFnTdbWPb(state, state.dataThermalComforts->AirTemp, thisZoneHB.ZoneAirHumRatAvgComf, state.dataEnvrn->OutBaroPress); // Metabolic rate of body (W/m2) (var RM, M) state.dataThermalComforts->ActLevel = GetCurrentScheduleValue(state, state.dataHeatBal->People(state.dataThermalComforts->PeopleNum).ActivityLevelPtr) / BodySurfAreaPierce; @@ -1478,17 +1473,18 @@ namespace ThermalComfort { if (!state.dataHeatBal->People(state.dataThermalComforts->PeopleNum).KSU) continue; state.dataThermalComforts->ZoneNum = state.dataHeatBal->People(state.dataThermalComforts->PeopleNum).ZonePtr; - if (state.dataRoomAirMod->IsZoneDV(state.dataThermalComforts->ZoneNum) || - state.dataRoomAirMod->IsZoneUI(state.dataThermalComforts->ZoneNum)) { - state.dataThermalComforts->AirTemp = state.dataRoomAirMod->TCMF(state.dataThermalComforts->ZoneNum); // PH 3/7/04 - } else { - state.dataThermalComforts->AirTemp = state.dataHeatBalFanSys->ZTAVComf(state.dataThermalComforts->ZoneNum); + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataThermalComforts->ZoneNum); + + state.dataThermalComforts->AirTemp = thisZoneHB.ZTAVComf; + if (state.dataRoomAirMod->anyNonMixingRoomAirModel) { + if (state.dataRoomAirMod->IsZoneDV(state.dataThermalComforts->ZoneNum) || + state.dataRoomAirMod->IsZoneUI(state.dataThermalComforts->ZoneNum)) { + state.dataThermalComforts->AirTemp = state.dataRoomAirMod->TCMF(state.dataThermalComforts->ZoneNum); // PH 3/7/04 + } } state.dataThermalComforts->RadTemp = CalcRadTemp(state, state.dataThermalComforts->PeopleNum); - state.dataThermalComforts->RelHum = PsyRhFnTdbWPb(state, - state.dataThermalComforts->AirTemp, - state.dataHeatBalFanSys->ZoneAirHumRatAvgComf(state.dataThermalComforts->ZoneNum), - state.dataEnvrn->OutBaroPress); + state.dataThermalComforts->RelHum = + PsyRhFnTdbWPb(state, state.dataThermalComforts->AirTemp, thisZoneHB.ZoneAirHumRatAvgComf, state.dataEnvrn->OutBaroPress); state.dataThermalComforts->ActLevel = GetCurrentScheduleValue(state, state.dataHeatBal->People(state.dataThermalComforts->PeopleNum).ActivityLevelPtr) / BodySurfArea; state.dataThermalComforts->WorkEff = @@ -2144,7 +2140,7 @@ namespace ThermalComfort { state, "Zone areas*inside surface emissivities are summing to zero, for Zone=\"" + state.dataHeatBal->Zone(ZoneNum).Name + "\""); ShowContinueError(state, "As a result, MAT will be used for MRT when calculating a surface weighted MRT for this zone."); state.dataThermalComforts->FirstTimeError = false; - CalcSurfaceWeightedMRT = state.dataHeatBalFanSys->MAT(ZoneNum); + CalcSurfaceWeightedMRT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; if (AverageWithSurface) { CalcSurfaceWeightedMRT = 0.5 * (state.dataHeatBalSurf->SurfInsideTempHist(1)(SurfNum) + CalcSurfaceWeightedMRT); } @@ -2284,7 +2280,6 @@ namespace ThermalComfort { // SUBROUTINE LOCAL VARIABLE DECLARATIONS: Real64 OperTemp; - Real64 HumidRatio; Real64 CurAirTemp; Real64 CurMeanRadiantTemp; Real64 NumberOccupants; @@ -2314,16 +2309,17 @@ namespace ThermalComfort { // loop through the zones and determine if in simple ashrae 55 comfort regions for (iZone = 1; iZone <= state.dataGlobal->NumOfZones; ++iZone) { if (state.dataThermalComforts->ThermalComfortInASH55(iZone).ZoneIsOccupied) { + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(iZone); // keep track of occupied hours state.dataThermalComforts->ZoneOccHrs(iZone) += state.dataGlobal->TimeStepZone; - if (state.dataRoomAirMod->IsZoneDV(iZone) || state.dataRoomAirMod->IsZoneUI(iZone)) { - CurAirTemp = state.dataRoomAirMod->TCMF(iZone); - } else { - CurAirTemp = state.dataHeatBalFanSys->ZTAVComf(iZone); + CurAirTemp = thisZoneHB.ZTAVComf; + if (state.dataRoomAirMod->anyNonMixingRoomAirModel) { + if (state.dataRoomAirMod->IsZoneDV(iZone) || state.dataRoomAirMod->IsZoneUI(iZone)) { + CurAirTemp = state.dataRoomAirMod->TCMF(iZone); + } } CurMeanRadiantTemp = state.dataHeatBal->ZoneMRT(iZone); OperTemp = CurAirTemp * 0.5 + CurMeanRadiantTemp * 0.5; - HumidRatio = state.dataHeatBalFanSys->ZoneAirHumRatAvgComf(iZone); // for debugging // ThermalComfortInASH55(iZone)%dCurAirTemp = CurAirTemp // ThermalComfortInASH55(iZone)%dCurMeanRadiantTemp = CurMeanRadiantTemp @@ -2352,9 +2348,11 @@ namespace ThermalComfort { // 7 28.3 Summer 0.000 // 8 25.1 Summer 0.000 // check summer clothing conditions - isComfortableWithSummerClothes = isInQuadrilateral(OperTemp, HumidRatio, 25.1, 0.0, 23.6, 0.012, 26.8, 0.012, 28.3, 0.0); + isComfortableWithSummerClothes = + isInQuadrilateral(OperTemp, thisZoneHB.ZoneAirHumRatAvgComf, 25.1, 0.0, 23.6, 0.012, 26.8, 0.012, 28.3, 0.0); // check winter clothing conditions - isComfortableWithWinterClothes = isInQuadrilateral(OperTemp, HumidRatio, 21.7, 0.0, 19.6, 0.012, 23.9, 0.012, 26.3, 0.0); + isComfortableWithWinterClothes = + isInQuadrilateral(OperTemp, thisZoneHB.ZoneAirHumRatAvgComf, 21.7, 0.0, 19.6, 0.012, 23.9, 0.012, 26.3, 0.0); if (isComfortableWithSummerClothes) { state.dataThermalComforts->ThermalComfortInASH55(iZone).timeNotSummer = 0.0; } else { @@ -2538,9 +2536,11 @@ namespace ThermalComfort { deltaT = state.dataHeatBalFanSys->TempTstatAir(iZone) - state.dataHeatBalFanSys->ZoneThermostatSetPointLo(iZone); } else { if (state.dataZoneTempPredictorCorrector->NumOnOffCtrZone > 0) { - deltaT = state.dataHeatBalFanSys->ZTAV(iZone) - state.dataHeatBalFanSys->ZoneThermostatSetPointLoAver(iZone); + deltaT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(iZone).ZTAV - + state.dataHeatBalFanSys->ZoneThermostatSetPointLoAver(iZone); } else { - deltaT = state.dataHeatBalFanSys->ZTAV(iZone) - state.dataHeatBalFanSys->ZoneThermostatSetPointLo(iZone); + deltaT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(iZone).ZTAV - + state.dataHeatBalFanSys->ZoneThermostatSetPointLo(iZone); } } if (deltaT < deviationFromSetPtThresholdHtg) { @@ -2562,9 +2562,11 @@ namespace ThermalComfort { deltaT = state.dataHeatBalFanSys->TempTstatAir(iZone) - state.dataHeatBalFanSys->ZoneThermostatSetPointHi(iZone); } else { if (state.dataZoneTempPredictorCorrector->NumOnOffCtrZone > 0) { - deltaT = state.dataHeatBalFanSys->ZTAV(iZone) - state.dataHeatBalFanSys->ZoneThermostatSetPointHiAver(iZone); + deltaT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(iZone).ZTAV - + state.dataHeatBalFanSys->ZoneThermostatSetPointHiAver(iZone); } else { - deltaT = state.dataHeatBalFanSys->ZTAV(iZone) - state.dataHeatBalFanSys->ZoneThermostatSetPointHi(iZone); + deltaT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(iZone).ZTAV - + state.dataHeatBalFanSys->ZoneThermostatSetPointHi(iZone); } } @@ -2867,11 +2869,12 @@ namespace ThermalComfort { ++state.dataThermalComforts->PeopleNum) { if (!state.dataHeatBal->People(state.dataThermalComforts->PeopleNum).AdaptiveASH55) continue; state.dataThermalComforts->ZoneNum = state.dataHeatBal->People(state.dataThermalComforts->PeopleNum).ZonePtr; - if (state.dataRoomAirMod->IsZoneDV(state.dataThermalComforts->ZoneNum) || - state.dataRoomAirMod->IsZoneUI(state.dataThermalComforts->ZoneNum)) { - state.dataThermalComforts->AirTemp = state.dataRoomAirMod->TCMF(state.dataThermalComforts->ZoneNum); - } else { - state.dataThermalComforts->AirTemp = state.dataHeatBalFanSys->ZTAVComf(state.dataThermalComforts->ZoneNum); + state.dataThermalComforts->AirTemp = state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataThermalComforts->ZoneNum).ZTAVComf; + if (state.dataRoomAirMod->anyNonMixingRoomAirModel) { + if (state.dataRoomAirMod->IsZoneDV(state.dataThermalComforts->ZoneNum) || + state.dataRoomAirMod->IsZoneUI(state.dataThermalComforts->ZoneNum)) { + state.dataThermalComforts->AirTemp = state.dataRoomAirMod->TCMF(state.dataThermalComforts->ZoneNum); + } } state.dataThermalComforts->RadTemp = CalcRadTemp(state, state.dataThermalComforts->PeopleNum); state.dataThermalComforts->OpTemp = (state.dataThermalComforts->AirTemp + state.dataThermalComforts->RadTemp) / 2.0; @@ -3077,11 +3080,12 @@ namespace ThermalComfort { ++state.dataThermalComforts->PeopleNum) { if (!state.dataHeatBal->People(state.dataThermalComforts->PeopleNum).AdaptiveCEN15251) continue; state.dataThermalComforts->ZoneNum = state.dataHeatBal->People(state.dataThermalComforts->PeopleNum).ZonePtr; - if (state.dataRoomAirMod->IsZoneDV(state.dataThermalComforts->ZoneNum) || - state.dataRoomAirMod->IsZoneUI(state.dataThermalComforts->ZoneNum)) { - state.dataThermalComforts->AirTemp = state.dataRoomAirMod->TCMF(state.dataThermalComforts->ZoneNum); - } else { - state.dataThermalComforts->AirTemp = state.dataHeatBalFanSys->ZTAVComf(state.dataThermalComforts->ZoneNum); + state.dataThermalComforts->AirTemp = state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataThermalComforts->ZoneNum).ZTAVComf; + if (state.dataRoomAirMod->anyNonMixingRoomAirModel) { + if (state.dataRoomAirMod->IsZoneDV(state.dataThermalComforts->ZoneNum) || + state.dataRoomAirMod->IsZoneUI(state.dataThermalComforts->ZoneNum)) { + state.dataThermalComforts->AirTemp = state.dataRoomAirMod->TCMF(state.dataThermalComforts->ZoneNum); + } } state.dataThermalComforts->RadTemp = CalcRadTemp(state, state.dataThermalComforts->PeopleNum); state.dataThermalComforts->OpTemp = (state.dataThermalComforts->AirTemp + state.dataThermalComforts->RadTemp) / 2.0; diff --git a/src/EnergyPlus/UFADManager.cc b/src/EnergyPlus/UFADManager.cc index 73b16fba9ad..ef4ddbdcc19 100644 --- a/src/EnergyPlus/UFADManager.cc +++ b/src/EnergyPlus/UFADManager.cc @@ -73,6 +73,7 @@ #include #include #include +#include namespace EnergyPlus::UFADManager { @@ -664,7 +665,6 @@ void HcUCSDUF(EnergyPlusData &state, int const ZoneNum, Real64 const FractionHei // the interface subzone height. // Using/Aliasing - using namespace DataHeatBalFanSys; using namespace DataEnvironment; using namespace DataHeatBalance; @@ -1000,7 +1000,6 @@ void CalcUCSDUI(EnergyPlusData &state, int const ZoneNum) // index number for th // Using/Aliasing using Psychrometrics::PsyCpAirFnW; using Psychrometrics::PsyRhoAirFnPbTdbW; - using namespace DataHeatBalFanSys; auto &TimeStepSys = state.dataHVACGlobal->TimeStepSys; using InternalHeatGains::SumInternalConvectionGainsByTypes; using InternalHeatGains::SumReturnAirConvectionGainsByTypes; @@ -1056,7 +1055,6 @@ void CalcUCSDUI(EnergyPlusData &state, int const ZoneNum) // index number for th Real64 ThrowAngle; // diffuser slot angle relative to vertical [radians] Real64 SourceHeight; // height of plume sources above the floor [m] int Ctd; - Real64 AirCap; Real64 TempHistTerm; Real64 ZTAveraged; Real64 HeightUpSubzoneAve; // Height of center of upper air subzone @@ -1115,6 +1113,7 @@ void CalcUCSDUI(EnergyPlusData &state, int const ZoneNum) // index number for th } } + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); MIXFLAG = false; state.dataRoomAirMod->UFHcIn = state.dataHeatBalSurf->SurfHConvInt; SumSysMCp = 0.0; @@ -1155,17 +1154,16 @@ void CalcUCSDUI(EnergyPlusData &state, int const ZoneNum) // index number for th RetAirGains = SumReturnAirConvectionGainsByTypes(state, ZoneNum, IntGainTypesUpSubzone); ConvGainsUpSubzone += RetAirGains; } - ConvGains = ConvGainsOccSubzone + ConvGainsUpSubzone + state.dataHeatBalFanSys->SysDepZoneLoadsLagged(ZoneNum); + ConvGains = ConvGainsOccSubzone + ConvGainsUpSubzone + thisZoneHB.SysDepZoneLoadsLagged; ZoneEquipConfigNum = state.dataRoomAirMod->ZoneUCSDUI(UINum).ZoneEquipPtr; if (ZoneEquipConfigNum > 0) { for (InNodeIndex = 1; InNodeIndex <= state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).NumInletNodes; ++InNodeIndex) { NodeTemp = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).InletNode(InNodeIndex)).Temp; MassFlowRate = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).InletNode(InNodeIndex)).MassFlowRate; - CpAir = PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)); + CpAir = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat); SumSysMCp += MassFlowRate * CpAir; SumSysMCpT += MassFlowRate * CpAir * NodeTemp; - TotSysFlow += - MassFlowRate / PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, NodeTemp, state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)); + TotSysFlow += MassFlowRate / PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, NodeTemp, thisZoneHB.ZoneAirHumRat); TSupK += MassFlowRate * NodeTemp; SumSysM += MassFlowRate; } @@ -1176,12 +1174,10 @@ void CalcUCSDUI(EnergyPlusData &state, int const ZoneNum) // index number for th } } // mass flow times specific heat for infiltration, ventilation, mixing, earth tube - SumMCp = state.dataHeatBalFanSys->MCPI(ZoneNum) + state.dataHeatBalFanSys->MCPV(ZoneNum) + state.dataHeatBalFanSys->MCPM(ZoneNum) + - state.dataHeatBalFanSys->MCPE(ZoneNum) + state.dataHeatBalFanSys->MCPC(ZoneNum) + state.dataHeatBalFanSys->MDotCPOA(ZoneNum); + SumMCp = thisZoneHB.MCPI + thisZoneHB.MCPV + thisZoneHB.MCPM + thisZoneHB.MCPE + thisZoneHB.MCPC + thisZoneHB.MDotCPOA; // mass flow times specific heat times temperature for infiltration, ventilation, mixing, earth tube - SumMCpT = state.dataHeatBalFanSys->MCPTI(ZoneNum) + state.dataHeatBalFanSys->MCPTV(ZoneNum) + state.dataHeatBalFanSys->MCPTM(ZoneNum) + - state.dataHeatBalFanSys->MCPTE(ZoneNum) + state.dataHeatBalFanSys->MCPTC(ZoneNum) + - state.dataHeatBalFanSys->MDotCPOA(ZoneNum) * state.dataHeatBal->Zone(ZoneNum).OutDryBulbTemp; + SumMCpT = thisZoneHB.MCPTI + thisZoneHB.MCPTV + thisZoneHB.MCPTM + thisZoneHB.MCPTE + thisZoneHB.MCPTC + + thisZoneHB.MDotCPOA * state.dataHeatBal->Zone(ZoneNum).OutDryBulbTemp; MCp_Total = SumMCp + SumSysMCp; MCpT_Total = SumMCpT + SumSysMCpT; // For the York MIT diffusers (variable area) the area varies with the flow rate. Assume 400 ft/min velocity @@ -1202,7 +1198,7 @@ void CalcUCSDUI(EnergyPlusData &state, int const ZoneNum) // index number for th NumberOfPlumes = 1.0; NumDiffusersPerPlume = 1.0; } - if ((PowerInPlumes <= 0.0) || (TotSysFlow == 0.0) || (TSupK - DataGlobalConstants::KelvinConv) > state.dataHeatBalFanSys->MAT(ZoneNum)) { + if ((PowerInPlumes <= 0.0) || (TotSysFlow == 0.0) || (TSupK - DataGlobalConstants::KelvinConv) > thisZoneHB.MAT) { // The system will mix HeightFrac = 0.0; } else { @@ -1243,15 +1239,13 @@ void CalcUCSDUI(EnergyPlusData &state, int const ZoneNum) // index number for th state.dataHeatBal->Zone(ZoneNum).Volume * (state.dataRoomAirMod->HeightTransition(ZoneNum) - min(state.dataRoomAirMod->HeightTransition(ZoneNum), 0.2)) / CeilingHeight * state.dataHeatBal->Zone(ZoneNum).ZoneVolCapMultpSens * - PsyRhoAirFnPbTdbW( - state, state.dataEnvrn->OutBaroPress, state.dataRoomAirMod->MATOC(ZoneNum), state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)) * - PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)) / (TimeStepSys * DataGlobalConstants::SecInHour); + PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, state.dataRoomAirMod->MATOC(ZoneNum), thisZoneHB.ZoneAirHumRat) * + PsyCpAirFnW(thisZoneHB.ZoneAirHumRat) / (TimeStepSys * DataGlobalConstants::SecInHour); state.dataRoomAirMod->AIRRATMX(ZoneNum) = state.dataHeatBal->Zone(ZoneNum).Volume * (CeilingHeight - state.dataRoomAirMod->HeightTransition(ZoneNum)) / CeilingHeight * state.dataHeatBal->Zone(ZoneNum).ZoneVolCapMultpSens * - PsyRhoAirFnPbTdbW( - state, state.dataEnvrn->OutBaroPress, state.dataRoomAirMod->MATMX(ZoneNum), state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)) * - PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)) / (TimeStepSys * DataGlobalConstants::SecInHour); + PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, state.dataRoomAirMod->MATMX(ZoneNum), thisZoneHB.ZoneAirHumRat) * + PsyCpAirFnW(thisZoneHB.ZoneAirHumRat) / (TimeStepSys * DataGlobalConstants::SecInHour); if (state.dataHVACGlobal->UseZoneTimeStepHistory) { state.dataRoomAirMod->ZTM3OC(ZoneNum) = state.dataRoomAirMod->XM3TOC(ZoneNum); @@ -1272,20 +1266,20 @@ void CalcUCSDUI(EnergyPlusData &state, int const ZoneNum) // index number for th state.dataRoomAirMod->ZTM1MX(ZoneNum) = state.dataRoomAirMod->DSXMATMX(ZoneNum); } - AirCap = state.dataRoomAirMod->AIRRATOC(ZoneNum); + Real64 AirCap = state.dataRoomAirMod->AIRRATOC(ZoneNum); TempHistTerm = AirCap * (3.0 * state.dataRoomAirMod->ZTM1OC(ZoneNum) - (3.0 / 2.0) * state.dataRoomAirMod->ZTM2OC(ZoneNum) + (1.0 / 3.0) * state.dataRoomAirMod->ZTM3OC(ZoneNum)); // Formerly CoefSumha, coef in zone temp equation with dimensions of h*A Real64 TempDepCoef = GainsFrac * state.dataUFADManager->HA_OC + MCp_Total; Real64 TempIndCoef = GainsFrac * (ConvGains + state.dataUFADManager->HAT_OC + state.dataUFADManager->HAT_MX - state.dataUFADManager->HA_MX * state.dataRoomAirMod->ZTMX(ZoneNum)) + - MCpT_Total + state.dataHeatBalFanSys->NonAirSystemResponse(ZoneNum) / ZoneMult; + MCpT_Total + thisZoneHB.NonAirSystemResponse / ZoneMult; switch (state.dataHeatBal->ZoneAirSolutionAlgo) { case DataHeatBalance::SolutionAlgo::ThirdOrder: { state.dataRoomAirMod->ZTOC(ZoneNum) = (TempHistTerm + GainsFrac * (ConvGains + state.dataUFADManager->HAT_OC + state.dataUFADManager->HAT_MX - state.dataUFADManager->HA_MX * state.dataRoomAirMod->ZTMX(ZoneNum)) + - MCpT_Total + state.dataHeatBalFanSys->NonAirSystemResponse(ZoneNum) / ZoneMult) / + MCpT_Total + thisZoneHB.NonAirSystemResponse / ZoneMult) / ((11.0 / 6.0) * AirCap + GainsFrac * state.dataUFADManager->HA_OC + MCp_Total); } break; case DataHeatBalance::SolutionAlgo::AnalyticalSolution: { @@ -1356,12 +1350,12 @@ void CalcUCSDUI(EnergyPlusData &state, int const ZoneNum) // index number for th state.dataRoomAirMod->AvgTempGrad(ZoneNum) = 0.0; state.dataRoomAirMod->MaxTempGrad(ZoneNum) = 0.0; state.dataRoomAirMod->AirModel(ZoneNum).SimAirModel = false; - AirCap = state.dataHeatBalFanSys->AIRRAT(ZoneNum); - TempHistTerm = AirCap * (3.0 * state.dataHeatBalFanSys->ZTM1(ZoneNum) - (3.0 / 2.0) * state.dataHeatBalFanSys->ZTM2(ZoneNum) + - (1.0 / 3.0) * state.dataHeatBalFanSys->ZTM3(ZoneNum)); + Real64 AirCap = thisZoneHB.AirPowerCap; + TempHistTerm = AirCap * (3.0 * thisZoneHB.ZTM[0] - (3.0 / 2.0) * thisZoneHB.ZTM[1] + (1.0 / 3.0) * thisZoneHB.ZTM[2]); for (Ctd = 1; Ctd <= 3; ++Ctd) { Real64 TempDepCoef = state.dataUFADManager->HA_MX + state.dataUFADManager->HA_OC + MCp_Total; + Real64 const thisZoneT1 = thisZoneHB.ZoneT1; // Formerly CoefSumhat, coef in zone temp equation with dimensions of h*A(T1 Real64 TempIndCoef = ConvGains + state.dataUFADManager->HAT_MX + state.dataUFADManager->HAT_OC + MCpT_Total; switch (state.dataHeatBal->ZoneAirSolutionAlgo) { @@ -1371,15 +1365,13 @@ void CalcUCSDUI(EnergyPlusData &state, int const ZoneNum) // index number for th } break; case DataHeatBalance::SolutionAlgo::AnalyticalSolution: { if (TempDepCoef == 0.0) { // B=0 - ZTAveraged = state.dataHeatBalFanSys->ZoneT1(ZoneNum) + TempIndCoef / AirCap; + ZTAveraged = thisZoneT1 + TempIndCoef / AirCap; } else { - ZTAveraged = - (state.dataHeatBalFanSys->ZoneT1(ZoneNum) - TempIndCoef / TempDepCoef) * std::exp(min(700.0, -TempDepCoef / AirCap)) + - TempIndCoef / TempDepCoef; + ZTAveraged = (thisZoneT1 - TempIndCoef / TempDepCoef) * std::exp(min(700.0, -TempDepCoef / AirCap)) + TempIndCoef / TempDepCoef; } } break; case DataHeatBalance::SolutionAlgo::EulerMethod: { - ZTAveraged = (AirCap * state.dataHeatBalFanSys->ZoneT1(ZoneNum) + TempIndCoef) / (AirCap + TempDepCoef); + ZTAveraged = (AirCap * thisZoneT1 + TempIndCoef) / (AirCap + TempDepCoef); } break; default: break; @@ -1397,15 +1389,13 @@ void CalcUCSDUI(EnergyPlusData &state, int const ZoneNum) // index number for th } break; case DataHeatBalance::SolutionAlgo::AnalyticalSolution: { if (TempDepCoef == 0.0) { // B=0 - ZTAveraged = state.dataHeatBalFanSys->ZoneT1(ZoneNum) + TempIndCoef / AirCap; + ZTAveraged = thisZoneT1 + TempIndCoef / AirCap; } else { - ZTAveraged = - (state.dataHeatBalFanSys->ZoneT1(ZoneNum) - TempIndCoef / TempDepCoef) * std::exp(min(700.0, -TempDepCoef / AirCap)) + - TempIndCoef / TempDepCoef; + ZTAveraged = (thisZoneT1 - TempIndCoef / TempDepCoef) * std::exp(min(700.0, -TempDepCoef / AirCap)) + TempIndCoef / TempDepCoef; } } break; case DataHeatBalance::SolutionAlgo::EulerMethod: { - ZTAveraged = (AirCap * state.dataHeatBalFanSys->ZoneT1(ZoneNum) + TempIndCoef) / (AirCap + TempDepCoef); + ZTAveraged = (AirCap * thisZoneT1 + TempIndCoef) / (AirCap + TempDepCoef); } break; default: break; @@ -1520,7 +1510,6 @@ void CalcUCSDUE(EnergyPlusData &state, int const ZoneNum) // index number for th // Using/Aliasing using Psychrometrics::PsyCpAirFnW; using Psychrometrics::PsyRhoAirFnPbTdbW; - using namespace DataHeatBalFanSys; auto &TimeStepSys = state.dataHVACGlobal->TimeStepSys; using InternalHeatGains::SumInternalConvectionGainsByTypes; using InternalHeatGains::SumReturnAirConvectionGainsByTypes; @@ -1638,6 +1627,7 @@ void CalcUCSDUE(EnergyPlusData &state, int const ZoneNum) // index number for th } } + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); HeightFrac = 0.0; MIXFLAG = false; state.dataRoomAirMod->UFHcIn = state.dataHeatBalSurf->SurfHConvInt; @@ -1681,17 +1671,16 @@ void CalcUCSDUE(EnergyPlusData &state, int const ZoneNum) // index number for th RetAirGains = SumReturnAirConvectionGainsByTypes(state, ZoneNum, IntGainTypesUpSubzone); ConvGainsUpSubzone += RetAirGains; } - ConvGains = ConvGainsOccSubzone + ConvGainsUpSubzone + state.dataHeatBalFanSys->SysDepZoneLoadsLagged(ZoneNum); + ConvGains = ConvGainsOccSubzone + ConvGainsUpSubzone + thisZoneHB.SysDepZoneLoadsLagged; ZoneEquipConfigNum = state.dataRoomAirMod->ZoneUCSDUE(UINum).ZoneEquipPtr; if (ZoneEquipConfigNum > 0) { for (InNodeIndex = 1; InNodeIndex <= state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).NumInletNodes; ++InNodeIndex) { NodeTemp = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).InletNode(InNodeIndex)).Temp; MassFlowRate = state.dataLoopNodes->Node(state.dataZoneEquip->ZoneEquipConfig(ZoneEquipConfigNum).InletNode(InNodeIndex)).MassFlowRate; - CpAir = PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)); + CpAir = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat); SumSysMCp += MassFlowRate * CpAir; SumSysMCpT += MassFlowRate * CpAir * NodeTemp; - TotSysFlow += - MassFlowRate / PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, NodeTemp, state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)); + TotSysFlow += MassFlowRate / PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, NodeTemp, thisZoneHB.ZoneAirHumRat); TSupK += MassFlowRate * NodeTemp; SumSysM += MassFlowRate; } @@ -1702,11 +1691,9 @@ void CalcUCSDUE(EnergyPlusData &state, int const ZoneNum) // index number for th } } // mass flow times specific heat for infiltration, ventilation, mixing - SumMCp = state.dataHeatBalFanSys->MCPI(ZoneNum) + state.dataHeatBalFanSys->MCPV(ZoneNum) + state.dataHeatBalFanSys->MCPM(ZoneNum) + - state.dataHeatBalFanSys->MDotCPOA(ZoneNum); + SumMCp = thisZoneHB.MCPI + thisZoneHB.MCPV + thisZoneHB.MCPM + thisZoneHB.MDotCPOA; // mass flow times specific heat times temperature for infiltration, ventilation, mixing - SumMCpT = state.dataHeatBalFanSys->MCPTI(ZoneNum) + state.dataHeatBalFanSys->MCPTV(ZoneNum) + state.dataHeatBalFanSys->MCPTM(ZoneNum) + - state.dataHeatBalFanSys->MDotCPOA(ZoneNum) * state.dataHeatBal->Zone(ZoneNum).OutDryBulbTemp; + SumMCpT = thisZoneHB.MCPTI + thisZoneHB.MCPTV + thisZoneHB.MCPTM + thisZoneHB.MDotCPOA * state.dataHeatBal->Zone(ZoneNum).OutDryBulbTemp; MCp_Total = SumMCp + SumSysMCp; MCpT_Total = SumMCpT + SumSysMCpT; @@ -1733,7 +1720,7 @@ void CalcUCSDUE(EnergyPlusData &state, int const ZoneNum) // index number for th NumberOfPlumes = 1.0; NumDiffusersPerPlume = 1.0; } - if ((PowerInPlumes <= 0.0) || (TotSysFlow == 0.0) || (TSupK - DataGlobalConstants::KelvinConv) > state.dataHeatBalFanSys->MAT(ZoneNum)) { + if ((PowerInPlumes <= 0.0) || (TotSysFlow == 0.0) || (TSupK - DataGlobalConstants::KelvinConv) > thisZoneHB.MAT) { // The system will mix HeightFrac = 0.0; } else { @@ -1806,15 +1793,13 @@ void CalcUCSDUE(EnergyPlusData &state, int const ZoneNum) // index number for th state.dataHeatBal->Zone(ZoneNum).Volume * (state.dataRoomAirMod->HeightTransition(ZoneNum) - min(state.dataRoomAirMod->HeightTransition(ZoneNum), 0.2)) / CeilingHeight * state.dataHeatBal->Zone(ZoneNum).ZoneVolCapMultpSens * - PsyRhoAirFnPbTdbW( - state, state.dataEnvrn->OutBaroPress, state.dataRoomAirMod->MATOC(ZoneNum), state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)) * - PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)) / (TimeStepSys * DataGlobalConstants::SecInHour); + PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, state.dataRoomAirMod->MATOC(ZoneNum), thisZoneHB.ZoneAirHumRat) * + PsyCpAirFnW(thisZoneHB.ZoneAirHumRat) / (TimeStepSys * DataGlobalConstants::SecInHour); state.dataRoomAirMod->AIRRATMX(ZoneNum) = state.dataHeatBal->Zone(ZoneNum).Volume * (CeilingHeight - state.dataRoomAirMod->HeightTransition(ZoneNum)) / CeilingHeight * state.dataHeatBal->Zone(ZoneNum).ZoneVolCapMultpSens * - PsyRhoAirFnPbTdbW( - state, state.dataEnvrn->OutBaroPress, state.dataRoomAirMod->MATMX(ZoneNum), state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)) * - PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)) / (TimeStepSys * DataGlobalConstants::SecInHour); + PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, state.dataRoomAirMod->MATMX(ZoneNum), thisZoneHB.ZoneAirHumRat) * + PsyCpAirFnW(thisZoneHB.ZoneAirHumRat) / (TimeStepSys * DataGlobalConstants::SecInHour); if (state.dataHVACGlobal->UseZoneTimeStepHistory) { state.dataRoomAirMod->ZTM3OC(ZoneNum) = state.dataRoomAirMod->XM3TOC(ZoneNum); @@ -1841,13 +1826,13 @@ void CalcUCSDUE(EnergyPlusData &state, int const ZoneNum) // index number for th TempDepCoef = GainsFrac * state.dataUFADManager->HA_OC + MCp_Total; TempIndCoef = GainsFrac * (ConvGains + state.dataUFADManager->HAT_OC + state.dataUFADManager->HAT_MX - state.dataUFADManager->HA_MX * state.dataRoomAirMod->ZTMX(ZoneNum)) + - MCpT_Total + state.dataHeatBalFanSys->NonAirSystemResponse(ZoneNum) / ZoneMult; + MCpT_Total + thisZoneHB.NonAirSystemResponse / ZoneMult; switch (state.dataHeatBal->ZoneAirSolutionAlgo) { case DataHeatBalance::SolutionAlgo::ThirdOrder: { state.dataRoomAirMod->ZTOC(ZoneNum) = (TempHistTerm + GainsFrac * (ConvGains + state.dataUFADManager->HAT_OC + state.dataUFADManager->HAT_MX - state.dataUFADManager->HA_MX * state.dataRoomAirMod->ZTMX(ZoneNum)) + - MCpT_Total + state.dataHeatBalFanSys->NonAirSystemResponse(ZoneNum) / ZoneMult) / + MCpT_Total + thisZoneHB.NonAirSystemResponse / ZoneMult) / ((11.0 / 6.0) * AirCap + GainsFrac * state.dataUFADManager->HA_OC + MCp_Total); } break; case DataHeatBalance::SolutionAlgo::AnalyticalSolution: { @@ -1917,13 +1902,13 @@ void CalcUCSDUE(EnergyPlusData &state, int const ZoneNum) // index number for th HeightFrac * CeilingHeight < state.dataUFADManager->ThickOccupiedSubzoneMin) { MIXFLAG = true; HeightFrac = 0.0; + Real64 const thisZoneT1 = thisZoneHB.ZoneT1; state.dataRoomAirMod->AvgTempGrad(ZoneNum) = 0.0; state.dataRoomAirMod->MaxTempGrad(ZoneNum) = 0.0; state.dataRoomAirMod->AirModel(ZoneNum).SimAirModel = false; - AirCap = state.dataHeatBalFanSys->AIRRAT(ZoneNum); - TempHistTerm = AirCap * (3.0 * state.dataHeatBalFanSys->ZTM1(ZoneNum) - (3.0 / 2.0) * state.dataHeatBalFanSys->ZTM2(ZoneNum) + - (1.0 / 3.0) * state.dataHeatBalFanSys->ZTM3(ZoneNum)); + Real64 AirCap = thisZoneHB.AirPowerCap; + TempHistTerm = AirCap * (3.0 * thisZoneHB.ZTM[0] - (3.0 / 2.0) * thisZoneHB.ZTM[1] + (1.0 / 3.0) * thisZoneHB.ZTM[2]); for (Ctd = 1; Ctd <= 3; ++Ctd) { TempDepCoef = state.dataUFADManager->HA_MX + state.dataUFADManager->HA_OC + MCp_Total; @@ -1935,15 +1920,13 @@ void CalcUCSDUE(EnergyPlusData &state, int const ZoneNum) // index number for th } break; case DataHeatBalance::SolutionAlgo::AnalyticalSolution: { if (TempDepCoef == 0.0) { // B=0 - ZTAveraged = state.dataHeatBalFanSys->ZoneT1(ZoneNum) + TempIndCoef / AirCap; + ZTAveraged = thisZoneT1 + TempIndCoef / AirCap; } else { - ZTAveraged = - (state.dataHeatBalFanSys->ZoneT1(ZoneNum) - TempIndCoef / TempDepCoef) * std::exp(min(700.0, -TempDepCoef / AirCap)) + - TempIndCoef / TempDepCoef; + ZTAveraged = (thisZoneT1 - TempIndCoef / TempDepCoef) * std::exp(min(700.0, -TempDepCoef / AirCap)) + TempIndCoef / TempDepCoef; } } break; case DataHeatBalance::SolutionAlgo::EulerMethod: { - ZTAveraged = (AirCap * state.dataHeatBalFanSys->ZoneT1(ZoneNum) + TempIndCoef) / (AirCap + TempDepCoef); + ZTAveraged = (AirCap * thisZoneT1 + TempIndCoef) / (AirCap + TempDepCoef); } break; default: break; @@ -1961,15 +1944,13 @@ void CalcUCSDUE(EnergyPlusData &state, int const ZoneNum) // index number for th } break; case DataHeatBalance::SolutionAlgo::AnalyticalSolution: { if (TempDepCoef == 0.0) { // B=0 - ZTAveraged = state.dataHeatBalFanSys->ZoneT1(ZoneNum) + TempIndCoef / AirCap; + ZTAveraged = thisZoneT1 + TempIndCoef / AirCap; } else { - ZTAveraged = - (state.dataHeatBalFanSys->ZoneT1(ZoneNum) - TempIndCoef / TempDepCoef) * std::exp(min(700.0, -TempDepCoef / AirCap)) + - TempIndCoef / TempDepCoef; + ZTAveraged = (thisZoneT1 - TempIndCoef / TempDepCoef) * std::exp(min(700.0, -TempDepCoef / AirCap)) + TempIndCoef / TempDepCoef; } } break; case DataHeatBalance::SolutionAlgo::EulerMethod: { - ZTAveraged = (AirCap * state.dataHeatBalFanSys->ZoneT1(ZoneNum) + TempIndCoef) / (AirCap + TempDepCoef); + ZTAveraged = (AirCap * thisZoneT1 + TempIndCoef) / (AirCap + TempDepCoef); } break; default: break; diff --git a/src/EnergyPlus/UnitarySystem.cc b/src/EnergyPlus/UnitarySystem.cc index b4c02023cd2..2a903c01572 100644 --- a/src/EnergyPlus/UnitarySystem.cc +++ b/src/EnergyPlus/UnitarySystem.cc @@ -101,6 +101,7 @@ #include #include #include +#include namespace EnergyPlus { namespace UnitarySystems { @@ -8137,8 +8138,9 @@ namespace UnitarySystems { state.dataCoilCooingDX->coilCoolingDXs[this->m_CoolingCoilIndex].SubcoolReheatFlag)) { this->LoadSHR = ZoneLoad / (ZoneLoad + state.dataUnitarySystems->MoistureLoad * - Psychrometrics::PsyHgAirFnWTdb(state.dataHeatBalFanSys->ZoneAirHumRat(this->ControlZoneNum), - state.dataHeatBalFanSys->MAT(this->ControlZoneNum))); + Psychrometrics::PsyHgAirFnWTdb( + state.dataZoneTempPredictorCorrector->zoneHeatBalance(this->ControlZoneNum).ZoneAirHumRat, + state.dataZoneTempPredictorCorrector->zoneHeatBalance(this->ControlZoneNum).MAT)); if (this->LoadSHR < 0.0) { this->LoadSHR = 0.0; } diff --git a/src/EnergyPlus/VentilatedSlab.cc b/src/EnergyPlus/VentilatedSlab.cc index a10d9246079..f6030b3d2a7 100644 --- a/src/EnergyPlus/VentilatedSlab.cc +++ b/src/EnergyPlus/VentilatedSlab.cc @@ -92,6 +92,7 @@ #include #include #include +#include namespace EnergyPlus { @@ -1736,7 +1737,7 @@ namespace VentilatedSlab { // The first pass through in a particular time step ZoneNum = ventSlab.ZonePtr; state.dataVentilatedSlab->ZeroSourceSumHATsurf(ZoneNum) = - SumHATsurf(state, ZoneNum); // Set this to figure what part of the load the radiant system meets + state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state); // Set this to figure what part of the load the radiant system meets for (RadSurfNum = 1; RadSurfNum <= ventSlab.NumOfSurfaces; ++RadSurfNum) { SurfNum = ventSlab.SurfacePtr(RadSurfNum); state.dataVentilatedSlab->QRadSysSrcAvg(SurfNum) = 0.0; // Initialize this variable to zero (radiant system defaults to off) @@ -2753,11 +2754,12 @@ namespace VentilatedSlab { RadSurfNum = ventSlab.NumOfSurfaces; Tinlet = state.dataLoopNodes->Node(InletNode).Temp; Toutdoor = state.dataLoopNodes->Node(OutsideAirNode).Temp; + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); // Control Type Check switch (ventSlab.controlType) { case ControlType::MeanAirTemp: { - SetPointTemp = state.dataHeatBalFanSys->MAT(ZoneNum); + SetPointTemp = thisZoneHB.MAT; break; } case ControlType::MeanRadTemp: { @@ -2765,7 +2767,7 @@ namespace VentilatedSlab { break; } case ControlType::OperativeTemp: { - SetPointTemp = 0.5 * (state.dataHeatBalFanSys->MAT(ZoneNum) + state.dataHeatBal->ZoneMRT(ZoneNum)); + SetPointTemp = 0.5 * (thisZoneHB.MAT + state.dataHeatBal->ZoneMRT(ZoneNum)); break; } case ControlType::OutdoorDryBulbTemp: { @@ -2781,7 +2783,8 @@ namespace VentilatedSlab { break; } case ControlType::DewPointTemp: { - SetPointTemp = PsyTdpFnWPb(state, state.dataHeatBalFanSys->ZoneAirHumRat(ventSlab.ZonePtr), state.dataEnvrn->OutBaroPress); + SetPointTemp = PsyTdpFnWPb( + state, state.dataZoneTempPredictorCorrector->zoneHeatBalance(ventSlab.ZonePtr).ZoneAirHumRat, state.dataEnvrn->OutBaroPress); break; } default: { // Should never get here @@ -3710,6 +3713,7 @@ namespace VentilatedSlab { ZoneNum = ventSlab.ZonePtr; ZoneMult = double(state.dataHeatBal->Zone(ZoneNum).Multiplier * state.dataHeatBal->Zone(ZoneNum).ListMultiplier); AirMassFlow = state.dataLoopNodes->Node(ventSlab.RadInNode).MassFlowRate / ZoneMult; + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); if (state.dataVentilatedSlab->OperatingMode == HeatingMode) { @@ -3867,7 +3871,7 @@ namespace VentilatedSlab { state.dataLoopNodes->Node(FanOutletNode).Temp = state.dataLoopNodes->Node(ReturnAirNode).Temp; state.dataLoopNodes->Node(SlabInNode).Temp = state.dataLoopNodes->Node(FanOutletNode).Temp; } else if (ventSlab.SysConfg == VentilatedSlabConfig::SlabAndZone) { - state.dataLoopNodes->Node(ReturnAirNode).Temp = state.dataHeatBalFanSys->MAT(ZoneNum); + state.dataLoopNodes->Node(ReturnAirNode).Temp = thisZoneHB.MAT; state.dataLoopNodes->Node(SlabInNode).Temp = state.dataLoopNodes->Node(ReturnAirNode).Temp; state.dataLoopNodes->Node(FanOutletNode).Temp = state.dataLoopNodes->Node(SlabInNode).Temp; state.dataLoopNodes->Node(ZoneAirInNode).Temp = state.dataLoopNodes->Node(SlabInNode).Temp; @@ -3883,7 +3887,7 @@ namespace VentilatedSlab { // conditions. if (state.dataVentilatedSlab->OperatingMode == CoolingMode) { - DewPointTemp = PsyTdpFnWPb(state, state.dataHeatBalFanSys->ZoneAirHumRat(ventSlab.ZonePtr), state.dataEnvrn->OutBaroPress); + DewPointTemp = PsyTdpFnWPb(state, thisZoneHB.ZoneAirHumRat, state.dataEnvrn->OutBaroPress); for (RadSurfNum2 = 1; RadSurfNum2 <= ventSlab.NumOfSurfaces; ++RadSurfNum2) { if (state.dataHeatBalSurf->SurfInsideTempHist(1)(ventSlab.SurfacePtr(RadSurfNum2)) < (DewPointTemp + CondDeltaTemp)) { // Condensation warning--must shut off radiant system @@ -4030,7 +4034,7 @@ namespace VentilatedSlab { // state.dataLoopNodes->Node(ReturnAirNode)%Temp = MAT(Zonenum) } else { state.dataLoopNodes->Node(ZoneAirInNode).Temp = state.dataLoopNodes->Node(SlabInNode).Temp; - state.dataLoopNodes->Node(ReturnAirNode).Temp = state.dataHeatBalFanSys->MAT(ZoneNum); + state.dataLoopNodes->Node(ReturnAirNode).Temp = thisZoneHB.MAT; } } @@ -4134,8 +4138,9 @@ namespace VentilatedSlab { // conditions. if (state.dataVentilatedSlab->OperatingMode == CoolingMode) { - DewPointTemp = - PsyTdpFnWPb(state, state.dataHeatBalFanSys->ZoneAirHumRat(ventSlab.ZPtr(RadSurfNum)), state.dataEnvrn->OutBaroPress); + DewPointTemp = PsyTdpFnWPb(state, + state.dataZoneTempPredictorCorrector->zoneHeatBalance(ventSlab.ZPtr(RadSurfNum)).ZoneAirHumRat, + state.dataEnvrn->OutBaroPress); for (RadSurfNum2 = 1; RadSurfNum2 <= ventSlab.NumOfSurfaces; ++RadSurfNum2) { if (state.dataHeatBalSurf->SurfInsideTempHist(1)(ventSlab.SurfacePtr(RadSurfNum2)) < (DewPointTemp + CondDeltaTemp)) { // Condensation warning--must shut off radiant system @@ -4491,7 +4496,7 @@ namespace VentilatedSlab { state.dataLoopNodes->Node(AirOutletNode).Temp - TotalHeatSource / AirMassFlow / CpAppAir; state.dataLoopNodes->Node(ZoneInletNode).MassFlowRate = state.dataLoopNodes->Node(AirOutletNode).MassFlowRate; state.dataLoopNodes->Node(ZoneInletNode).HumRat = state.dataLoopNodes->Node(AirOutletNode).HumRat; - state.dataLoopNodes->Node(ventSlab.ReturnAirNode).Temp = state.dataHeatBalFanSys->MAT(ZoneNum); + state.dataLoopNodes->Node(ventSlab.ReturnAirNode).Temp = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT; } } else { @@ -4668,72 +4673,6 @@ namespace VentilatedSlab { return CalcVentSlabHXEffectTerm; } - Real64 SumHATsurf(EnergyPlusData &state, int const ZoneNum) // Zone number - { - - // FUNCTION INFORMATION: - // AUTHOR Peter Graham Ellis - // DATE WRITTEN July 2003 - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS FUNCTION: - // This function calculates the zone sum of Hc*Area*Tsurf. It replaces the old SUMHAT. - // The SumHATsurf code below is also in the CalcZoneSums subroutine in ZoneTempPredictorCorrector - // and should be updated accordingly. - - // METHODOLOGY EMPLOYED: - // na - - // REFERENCES: - // na - - // Using/Aliasing - using namespace DataSurfaces; - using namespace DataHeatBalance; - using namespace DataHeatBalSurface; - - // Return value - Real64 SumHATsurf; - - // Locals - // FUNCTION ARGUMENT DEFINITIONS: - - // FUNCTION LOCAL VARIABLE DECLARATIONS: - int SurfNum; // Surface number - Real64 Area; // Effective surface area - - SumHATsurf = 0.0; - - for (SurfNum = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst; SurfNum <= state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast; ++SurfNum) { - Area = state.dataSurface->Surface(SurfNum).Area; - - if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Window) { - if (ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum))) { - // The area is the shade or blind are = sum of the glazing area and the divider area (which is zero if no divider) - Area += state.dataSurface->SurfWinDividerArea(SurfNum); - } - - if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) { - // Window frame contribution - SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinFrameArea(SurfNum) * - (1.0 + state.dataSurface->SurfWinProjCorrFrIn(SurfNum)) * state.dataSurface->SurfWinFrameTempIn(SurfNum); - } - - if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0 && - !ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum))) { - // Window divider contribution (only from shade or blind for window with divider and interior shade or blind) - SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinDividerArea(SurfNum) * - (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) * state.dataSurface->SurfWinDividerTempIn(SurfNum); - } - } - - SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * Area * state.dataHeatBalSurf->SurfTempInTmp(SurfNum); - } - - return SumHATsurf; - } - void ReportVentilatedSlab(EnergyPlusData &state, int const Item) // Index for the ventilated slab under consideration within the derived types { diff --git a/src/EnergyPlus/VentilatedSlab.hh b/src/EnergyPlus/VentilatedSlab.hh index e6a9ecde1ab..f84bbccc03e 100644 --- a/src/EnergyPlus/VentilatedSlab.hh +++ b/src/EnergyPlus/VentilatedSlab.hh @@ -373,8 +373,6 @@ namespace VentilatedSlab { Real64 const CoreDiameter, // Inside diameter of the tubing in the radiant system, in m Real64 const CoreNumbers); - Real64 SumHATsurf(EnergyPlusData &state, int ZoneNum); // Zone number - void ReportVentilatedSlab(EnergyPlusData &state, int const Item); // Index for the ventilated slab under consideration within the derived types //***************************************************************************************** diff --git a/src/EnergyPlus/WaterThermalTanks.cc b/src/EnergyPlus/WaterThermalTanks.cc index fa16c2405c4..ecccc3311ea 100644 --- a/src/EnergyPlus/WaterThermalTanks.cc +++ b/src/EnergyPlus/WaterThermalTanks.cc @@ -60,7 +60,6 @@ #include #include #include -#include #include #include #include @@ -89,6 +88,7 @@ #include #include #include +#include namespace EnergyPlus::WaterThermalTanks { @@ -624,6 +624,7 @@ void CalcWaterThermalTankZoneGains(EnergyPlusData &state) for (int WaterThermalTankNum = 1; WaterThermalTankNum <= state.dataWaterThermalTanks->numWaterThermalTank; ++WaterThermalTankNum) { auto &Tank = state.dataWaterThermalTanks->WaterThermalTank(WaterThermalTankNum); if (Tank.AmbientTempZone == 0) continue; + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(Tank.AmbientTempZone); if (state.dataGlobal->DoingSizing) { // Initialize tank temperature to setpoint // (use HPWH or Desuperheater heating coil set point if applicable) @@ -646,21 +647,20 @@ void CalcWaterThermalTankZoneGains(EnergyPlusData &state) switch (Tank.WaterThermalTankType) { case DataPlant::PlantEquipmentType::WtrHeaterMixed: { QLossToZone = max(Tank.OnCycLossCoeff * Tank.OnCycLossFracToZone, Tank.OffCycLossCoeff * Tank.OffCycLossFracToZone) * - (TankTemp - state.dataHeatBalFanSys->MAT(Tank.AmbientTempZone)); + (TankTemp - thisZoneHB.MAT); break; } case DataPlant::PlantEquipmentType::WtrHeaterStratified: { QLossToZone = max(Tank.Node(1).OnCycLossCoeff * Tank.SkinLossFracToZone, Tank.Node(1).OffCycLossCoeff * Tank.SkinLossFracToZone) * - (TankTemp - state.dataHeatBalFanSys->MAT(Tank.AmbientTempZone)); + (TankTemp - thisZoneHB.MAT); break; } case DataPlant::PlantEquipmentType::ChilledWaterTankMixed: { - QLossToZone = Tank.OffCycLossCoeff * Tank.OffCycLossFracToZone * (TankTemp - state.dataHeatBalFanSys->MAT(Tank.AmbientTempZone)); + QLossToZone = Tank.OffCycLossCoeff * Tank.OffCycLossFracToZone * (TankTemp - thisZoneHB.MAT); break; } case DataPlant::PlantEquipmentType::ChilledWaterTankStratified: { - QLossToZone = - Tank.Node(1).OffCycLossCoeff * Tank.SkinLossFracToZone * (TankTemp - state.dataHeatBalFanSys->MAT(Tank.AmbientTempZone)); + QLossToZone = Tank.Node(1).OffCycLossCoeff * Tank.SkinLossFracToZone * (TankTemp - thisZoneHB.MAT); break; } default: @@ -6219,7 +6219,7 @@ void WaterThermalTankData::initialize(EnergyPlusData &state, bool const FirstHVA break; } case WTTAmbientTemp::TempZone: { - this->AmbientTemp = state.dataHeatBalFanSys->MAT(this->AmbientTempZone); + this->AmbientTemp = state.dataZoneTempPredictorCorrector->zoneHeatBalance(this->AmbientTempZone).MAT; break; } @@ -6387,7 +6387,7 @@ void WaterThermalTankData::initialize(EnergyPlusData &state, bool const FirstHVA switch (state.dataWaterThermalTanks->HPWaterHeater(HPNum).CrankcaseTempIndicator) { case CrankcaseHeaterControlTemp::Zone: { state.dataHVACGlobal->HPWHCrankcaseDBTemp = - state.dataHeatBalFanSys->MAT(state.dataWaterThermalTanks->HPWaterHeater(HPNum).AmbientTempZone); + state.dataZoneTempPredictorCorrector->zoneHeatBalance(state.dataWaterThermalTanks->HPWaterHeater(HPNum).AmbientTempZone).MAT; break; } case CrankcaseHeaterControlTemp::Outdoors: { diff --git a/src/EnergyPlus/WaterUse.cc b/src/EnergyPlus/WaterUse.cc index 1b0f9900752..83380d4c1d4 100644 --- a/src/EnergyPlus/WaterUse.cc +++ b/src/EnergyPlus/WaterUse.cc @@ -57,7 +57,6 @@ #include #include #include -#include #include #include #include @@ -73,6 +72,7 @@ #include #include #include +#include namespace EnergyPlus { @@ -1237,14 +1237,14 @@ namespace WaterUse { this->DrainMassFlowRate = this->TotalMassFlowRate; } else { + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(this->Zone); if (this->SensibleFracSchedule == 0) { this->SensibleRate = 0.0; this->SensibleEnergy = 0.0; } else { this->SensibleRate = ScheduleManager::GetCurrentScheduleValue(state, this->SensibleFracSchedule) * this->TotalMassFlowRate * - Psychrometrics::CPHW(DataGlobalConstants::InitConvTemp) * - (this->MixedTemp - state.dataHeatBalFanSys->MAT(this->Zone)); + Psychrometrics::CPHW(DataGlobalConstants::InitConvTemp) * (this->MixedTemp - thisZoneHB.MAT); this->SensibleEnergy = this->SensibleRate * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour; } @@ -1252,14 +1252,13 @@ namespace WaterUse { this->LatentRate = 0.0; this->LatentEnergy = 0.0; } else { - Real64 ZoneHumRat = state.dataHeatBalFanSys->ZoneAirHumRat(this->Zone); + Real64 ZoneHumRat = thisZoneHB.ZoneAirHumRat; Real64 ZoneHumRatSat = Psychrometrics::PsyWFnTdbRhPb(state, - state.dataHeatBalFanSys->MAT(this->Zone), + thisZoneHB.MAT, 1.0, state.dataEnvrn->OutBaroPress, RoutineName); // Humidratio at 100% relative humidity - Real64 RhoAirDry = - Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, state.dataHeatBalFanSys->MAT(this->Zone), 0.0); + Real64 RhoAirDry = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, thisZoneHB.MAT, 0.0); Real64 ZoneMassMax = (ZoneHumRatSat - ZoneHumRat) * RhoAirDry * state.dataHeatBal->Zone(this->Zone).Volume; // Max water that can be evaporated to zone Real64 FlowMassMax = @@ -1269,7 +1268,7 @@ namespace WaterUse { this->MoistureMass = ScheduleManager::GetCurrentScheduleValue(state, this->LatentFracSchedule) * MoistureMassMax; this->MoistureRate = this->MoistureMass / (state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour); - this->LatentRate = this->MoistureRate * Psychrometrics::PsyHfgAirFnWTdb(ZoneHumRat, state.dataHeatBalFanSys->MAT(this->Zone)); + this->LatentRate = this->MoistureRate * Psychrometrics::PsyHfgAirFnWTdb(ZoneHumRat, thisZoneHB.MAT); this->LatentEnergy = this->LatentRate * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour; } diff --git a/src/EnergyPlus/WindowComplexManager.cc b/src/EnergyPlus/WindowComplexManager.cc index a9e183ee47c..9dfb226fe6b 100644 --- a/src/EnergyPlus/WindowComplexManager.cc +++ b/src/EnergyPlus/WindowComplexManager.cc @@ -60,7 +60,6 @@ #include #include #include -#include #include #include #include @@ -79,6 +78,7 @@ #include #include #include +#include namespace EnergyPlus { @@ -102,7 +102,6 @@ namespace WindowComplexManager { using namespace DataHeatBalance; using namespace DataShadowingCombinations; using namespace Vectors; - using namespace DataHeatBalFanSys; // Parameters for gas definitions enum class GasCoeffs @@ -3315,14 +3314,15 @@ namespace WindowComplexManager { // air in case it needs to be sent to the zone (due to no return air determined in HVAC simulation) if (state.dataSurface->SurfWinAirflowDestination(SurfNum) == WindowAirFlowDestination::Indoor || state.dataSurface->SurfWinAirflowDestination(SurfNum) == WindowAirFlowDestination::Return) { + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); if (state.dataSurface->SurfWinAirflowSource(SurfNum) == WindowAirFlowSource::Indoor) { - InletAirHumRat = state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum); + InletAirHumRat = thisZoneHB.ZoneAirHumRat; } else { // AirflowSource = outside air InletAirHumRat = state.dataEnvrn->OutHumRat; } - ZoneTemp = state.dataHeatBalFanSys->MAT(ZoneNum); // this should be Tin (account for different reference temps) + ZoneTemp = thisZoneHB.MAT; // this should be Tin (account for different reference temps) CpAirOutlet = PsyCpAirFnW(InletAirHumRat); - CpAirZone = PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)); + CpAirZone = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat); ConvHeatGainToZoneAir = TotAirflowGap * (CpAirOutlet * (TAirflowGapOutletC)-CpAirZone * ZoneTemp); if (state.dataSurface->SurfWinAirflowDestination(SurfNum) == WindowAirFlowDestination::Indoor) { state.dataSurface->SurfWinConvHeatGainToZoneAir(SurfNum) = ConvHeatGainToZoneAir; diff --git a/src/EnergyPlus/WindowEquivalentLayer.cc b/src/EnergyPlus/WindowEquivalentLayer.cc index 216ece5ad7a..738a4f56524 100644 --- a/src/EnergyPlus/WindowEquivalentLayer.cc +++ b/src/EnergyPlus/WindowEquivalentLayer.cc @@ -58,7 +58,6 @@ #include #include #include -#include #include #include #include @@ -667,7 +666,6 @@ void EQLWindowSurfaceHeatBalance(EnergyPlusData &state, using Psychrometrics::PsyCpAirFnW; using Psychrometrics::PsyTdpFnWPb; using ScheduleManager::GetCurrentScheduleValue; - using namespace DataHeatBalFanSys; Real64 constexpr TOL(0.0001); // convergence tolerance diff --git a/src/EnergyPlus/WindowManager.cc b/src/EnergyPlus/WindowManager.cc index 4a497bb6696..c0bd2a21ec1 100644 --- a/src/EnergyPlus/WindowManager.cc +++ b/src/EnergyPlus/WindowManager.cc @@ -63,7 +63,6 @@ #include #include #include -#include #include #include #include @@ -83,6 +82,7 @@ #include #include #include +#include namespace EnergyPlus { @@ -125,7 +125,6 @@ namespace WindowManager { // Using/Aliasing using namespace DataEnvironment; using namespace DataHeatBalance; - using namespace DataHeatBalFanSys; using namespace DataSurfaces; // SUBROUTINE SPECIFICATIONS FOR MODULE WindowManager: @@ -2237,7 +2236,6 @@ namespace WindowManager { // SUBROUTINE ARGUMENT DEFINITIONS: // (temperature of innermost face) [C] - int ZoneNum; // Zone number corresponding to SurfNum int BlNum; // Window blind number int SurfNumAdj; // An interzone surface's number in the adjacent zone int ZoneNumAdj; // An interzone surface's adjacent zone number @@ -2287,6 +2285,7 @@ namespace WindowManager { auto &window(state.dataSurface->SurfaceWindow(SurfNum)); auto &surface(state.dataSurface->Surface(SurfNum)); int ConstrNum = state.dataSurface->SurfActiveConstruction(SurfNum); + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(surface.Zone); if (state.dataSurface->SurfWinWindowModelType(SurfNum) == WindowModel::BSDF) { @@ -2305,7 +2304,7 @@ namespace WindowManager { } state.dataWindowManager->hcout = HextConvCoeff; state.dataWindowManager->hcin = state.dataHeatBalSurf->SurfHConvInt(SurfNum); - state.dataWindowManager->tin = state.dataHeatBalFanSys->MAT(surface.Zone) + state.dataWindowManager->TKelvin; // Inside air temperature + state.dataWindowManager->tin = thisZoneHB.MAT + state.dataWindowManager->TKelvin; // Inside air temperature // This is code repeating and it is necessary to calculate report variables. Do not know // how to solve this in more elegant way :( @@ -2381,7 +2380,6 @@ namespace WindowManager { } // end new TC code - ZoneNum = surface.Zone; TotLay = state.dataConstruction->Construct(ConstrNum).TotLayers; TotGlassLay = state.dataConstruction->Construct(ConstrNum).TotGlassLayers; state.dataWindowManager->ngllayer = TotGlassLay; @@ -2747,7 +2745,7 @@ namespace WindowManager { // or, for airflow windows, on either or the two glass faces in the airflow gap if (!state.dataConstruction->Construct(surface.Construction).WindowTypeEQL) { InsideGlassTemp = state.dataWindowManager->thetas[2 * state.dataWindowManager->ngllayer - 1] - state.dataWindowManager->TKelvin; - RoomHumRat = state.dataHeatBalFanSys->ZoneAirHumRat(surface.Zone); + RoomHumRat = thisZoneHB.ZoneAirHumRat; RoomDewPoint = PsyTdpFnWPb(state, RoomHumRat, state.dataEnvrn->OutBaroPress); state.dataSurface->SurfWinInsideGlassCondensationFlag(SurfNum) = 0; if (InsideGlassTemp < RoomDewPoint) state.dataSurface->SurfWinInsideGlassCondensationFlag(SurfNum) = 1; @@ -3711,7 +3709,6 @@ namespace WindowManager { 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 - Real64 ZoneTemp = 0.0; // Zone air temperature (C) int InsideFaceIndex = 0; // intermediate variable for index of inside face in thetas state.dataWindowManager->nglfacep = state.dataWindowManager->nglface; @@ -3943,14 +3940,15 @@ namespace WindowManager { // air in case it needs to be sent to the zone (due to no return air determined in HVAC simulation) if (state.dataSurface->SurfWinAirflowDestination(SurfNum) == WindowAirFlowDestination::Indoor || state.dataSurface->SurfWinAirflowDestination(SurfNum) == WindowAirFlowDestination::Return) { + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); if (state.dataSurface->SurfWinAirflowSource(SurfNum) == WindowAirFlowSource::Indoor) { - InletAirHumRat = state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum); + InletAirHumRat = thisZoneHB.ZoneAirHumRat; } else { // AirflowSource = outside air InletAirHumRat = state.dataEnvrn->OutHumRat; } - ZoneTemp = state.dataHeatBalFanSys->MAT(ZoneNum); // this should be Tin (account for different reference temps) + Real64 ZoneTemp = thisZoneHB.MAT; // this should be Tin (account for different reference temps) CpAirOutlet = PsyCpAirFnW(InletAirHumRat); - CpAirZone = PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)); + CpAirZone = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat); state.dataSurface->SurfWinRetHeatGainToZoneAir(SurfNum) = TotAirflowGap * (CpAirOutlet * (TAirflowGapOutletC)-CpAirZone * ZoneTemp); if (state.dataSurface->SurfWinAirflowDestination(SurfNum) == WindowAirFlowDestination::Indoor) { @@ -6941,12 +6939,15 @@ namespace WindowManager { // init the surface convective and radiative adjustment ratio for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { - int const firstSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceFirst; - int const lastSurfWin = state.dataHeatBal->Zone(zoneNum).WindowSurfaceLast; - for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { - if (state.dataSurface->Surface(SurfNum).ExtBoundCond == ExternalEnvironment) { - int ConstrNum2 = state.dataSurface->Surface(SurfNum).Construction; - state.dataHeatBalSurf->SurfWinCoeffAdjRatio(SurfNum) = state.dataHeatBal->CoeffAdjRatio(ConstrNum2); + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + int const firstSurfWin = thisSpace.WindowSurfaceFirst; + int const lastSurfWin = thisSpace.WindowSurfaceLast; + for (int SurfNum = firstSurfWin; SurfNum <= lastSurfWin; ++SurfNum) { + if (state.dataSurface->Surface(SurfNum).ExtBoundCond == ExternalEnvironment) { + int ConstrNum2 = state.dataSurface->Surface(SurfNum).Construction; + state.dataHeatBalSurf->SurfWinCoeffAdjRatio(SurfNum) = state.dataHeatBal->CoeffAdjRatio(ConstrNum2); + } } } } diff --git a/src/EnergyPlus/WindowManagerExteriorThermal.cc b/src/EnergyPlus/WindowManagerExteriorThermal.cc index 0c17bb74db7..28b97e77241 100644 --- a/src/EnergyPlus/WindowManagerExteriorThermal.cc +++ b/src/EnergyPlus/WindowManagerExteriorThermal.cc @@ -50,7 +50,6 @@ #include #include #include -#include #include #include #include diff --git a/src/EnergyPlus/ZoneContaminantPredictorCorrector.cc b/src/EnergyPlus/ZoneContaminantPredictorCorrector.cc index 1fb96aac07b..a54c38dd155 100644 --- a/src/EnergyPlus/ZoneContaminantPredictorCorrector.cc +++ b/src/EnergyPlus/ZoneContaminantPredictorCorrector.cc @@ -95,7 +95,6 @@ namespace EnergyPlus::ZoneContaminantPredictorCorrector { // Using/Aliasing using namespace DataHVACGlobals; using namespace DataHeatBalance; -using namespace DataHeatBalFanSys; using namespace Psychrometrics; using namespace HybridModel; @@ -1719,6 +1718,7 @@ void PredictZoneContaminants(EnergyPlusData &state, // Update zone CO2 for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); if (ShortenTimeStepSys) { @@ -1865,8 +1865,8 @@ void PredictZoneContaminants(EnergyPlusData &state, if (ControlledCO2ZoneFlag) { Real64 RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, - state.dataHeatBalFanSys->ZT(ZoneNum), - state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum), + thisZoneHB.ZT, + thisZoneHB.ZoneAirHumRat, RoutineName); // The density of air // Calculate Co2 from infiltration + humidity added from latent load to determine system added/subtracted moisture. @@ -1877,6 +1877,7 @@ 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)) { @@ -1885,14 +1886,9 @@ void PredictZoneContaminants(EnergyPlusData &state, A = state.afn->exchangeData(ZoneNum).SumMHr + state.afn->exchangeData(ZoneNum).SumMMHr; } else { B = CO2Gain + - ((state.dataHeatBalFanSys->OAMFL(ZoneNum) + state.dataHeatBalFanSys->VAMFL(ZoneNum) + - state.dataHeatBalFanSys->EAMFL(ZoneNum) + state.dataHeatBalFanSys->CTMFL(ZoneNum)) * - state.dataContaminantBalance->OutdoorCO2) + - state.dataContaminantBalance->MixingMassFlowCO2(ZoneNum) + - state.dataHeatBalFanSys->MDotOA(ZoneNum) * state.dataContaminantBalance->OutdoorCO2; - A = state.dataHeatBalFanSys->OAMFL(ZoneNum) + state.dataHeatBalFanSys->VAMFL(ZoneNum) + state.dataHeatBalFanSys->EAMFL(ZoneNum) + - state.dataHeatBalFanSys->CTMFL(ZoneNum) + state.dataHeatBalFanSys->MixingMassFlowZone(ZoneNum) + - state.dataHeatBalFanSys->MDotOA(ZoneNum); + ((thisZoneHB.OAMFL + thisZoneHB.VAMFL + thisZoneHB.EAMFL + thisZoneHB.CTMFL) * state.dataContaminantBalance->OutdoorCO2) + + state.dataContaminantBalance->MixingMassFlowCO2(ZoneNum) + thisZoneHB.MDotOA * state.dataContaminantBalance->OutdoorCO2; + A = thisZoneHB.OAMFL + thisZoneHB.VAMFL + thisZoneHB.EAMFL + thisZoneHB.CTMFL + thisZoneHB.MixingMassFlowZone + thisZoneHB.MDotOA; } C = RhoAir * state.dataHeatBal->Zone(ZoneNum).Volume * state.dataHeatBal->Zone(ZoneNum).ZoneVolCapMultpCO2 / SysTimeStepInSeconds; @@ -1984,11 +1980,7 @@ void PredictZoneContaminants(EnergyPlusData &state, if (ControlledGCZoneFlag) { // The density of air - Real64 RhoAir = PsyRhoAirFnPbTdbW(state, - state.dataEnvrn->OutBaroPress, - state.dataHeatBalFanSys->ZT(ZoneNum), - state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum), - RoutineName); + Real64 RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, thisZoneHB.ZT, thisZoneHB.ZoneAirHumRat, RoutineName); // Calculate generic contaminant from infiltration + humidity added from latent load // to determine system added/subtracted moisture. @@ -1999,6 +1991,7 @@ 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)) { @@ -2007,14 +2000,9 @@ void PredictZoneContaminants(EnergyPlusData &state, A = state.afn->exchangeData(ZoneNum).SumMHr + state.afn->exchangeData(ZoneNum).SumMMHr; } else { B = GCGain + - ((state.dataHeatBalFanSys->OAMFL(ZoneNum) + state.dataHeatBalFanSys->VAMFL(ZoneNum) + - state.dataHeatBalFanSys->EAMFL(ZoneNum) + state.dataHeatBalFanSys->CTMFL(ZoneNum)) * - state.dataContaminantBalance->OutdoorGC) + - state.dataContaminantBalance->MixingMassFlowGC(ZoneNum) + - state.dataHeatBalFanSys->MDotOA(ZoneNum) * state.dataContaminantBalance->OutdoorGC; - A = state.dataHeatBalFanSys->OAMFL(ZoneNum) + state.dataHeatBalFanSys->VAMFL(ZoneNum) + state.dataHeatBalFanSys->EAMFL(ZoneNum) + - state.dataHeatBalFanSys->CTMFL(ZoneNum) + state.dataHeatBalFanSys->MixingMassFlowZone(ZoneNum) + - state.dataHeatBalFanSys->MDotOA(ZoneNum); + ((thisZoneHB.OAMFL + thisZoneHB.VAMFL + thisZoneHB.EAMFL + thisZoneHB.CTMFL) * state.dataContaminantBalance->OutdoorGC) + + state.dataContaminantBalance->MixingMassFlowGC(ZoneNum) + thisZoneHB.MDotOA * state.dataContaminantBalance->OutdoorGC; + A = thisZoneHB.OAMFL + thisZoneHB.VAMFL + thisZoneHB.EAMFL + thisZoneHB.CTMFL + thisZoneHB.MixingMassFlowZone + thisZoneHB.MDotOA; } C = RhoAir * state.dataHeatBal->Zone(ZoneNum).Volume * state.dataHeatBal->Zone(ZoneNum).ZoneVolCapMultpGenContam / SysTimeStepInSeconds; @@ -2201,6 +2189,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); 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. @@ -2214,23 +2203,15 @@ void InverseModelCO2(EnergyPlusData &state, Real64 SumSysMxCO2_HM = state.dataHeatBal->Zone(ZoneNum).ZoneMeasuredSupplyAirFlowRate * state.dataHeatBal->Zone(ZoneNum).ZoneMeasuredSupplyAirCO2Concentration; - AA = SumSysM_HM + state.dataHeatBalFanSys->VAMFL(ZoneNum) + state.dataHeatBalFanSys->EAMFL(ZoneNum) + - state.dataHeatBalFanSys->CTMFL(ZoneNum) + state.dataHeatBalFanSys->MixingMassFlowZone(ZoneNum) + - state.dataHeatBalFanSys->MDotOA(ZoneNum); + AA = SumSysM_HM + thisZoneHB.VAMFL + thisZoneHB.EAMFL + thisZoneHB.CTMFL + thisZoneHB.MixingMassFlowZone + thisZoneHB.MDotOA; BB = SumSysMxCO2_HM + CO2Gain + - ((state.dataHeatBalFanSys->VAMFL(ZoneNum) + state.dataHeatBalFanSys->EAMFL(ZoneNum) + state.dataHeatBalFanSys->CTMFL(ZoneNum)) * - state.dataContaminantBalance->OutdoorCO2) + - state.dataContaminantBalance->MixingMassFlowCO2(ZoneNum) + - state.dataHeatBalFanSys->MDotOA(ZoneNum) * state.dataContaminantBalance->OutdoorCO2; + ((thisZoneHB.VAMFL + thisZoneHB.EAMFL + thisZoneHB.CTMFL) * state.dataContaminantBalance->OutdoorCO2) + + state.dataContaminantBalance->MixingMassFlowCO2(ZoneNum) + thisZoneHB.MDotOA * state.dataContaminantBalance->OutdoorCO2; } else { - AA = state.dataHeatBalFanSys->VAMFL(ZoneNum) + state.dataHeatBalFanSys->EAMFL(ZoneNum) + state.dataHeatBalFanSys->CTMFL(ZoneNum) + - state.dataHeatBalFanSys->MixingMassFlowZone(ZoneNum) + state.dataHeatBalFanSys->MDotOA(ZoneNum); - BB = CO2Gain + - ((state.dataHeatBalFanSys->VAMFL(ZoneNum) + state.dataHeatBalFanSys->EAMFL(ZoneNum) + state.dataHeatBalFanSys->CTMFL(ZoneNum)) * - state.dataContaminantBalance->OutdoorCO2) + - state.dataContaminantBalance->MixingMassFlowCO2(ZoneNum) + - state.dataHeatBalFanSys->MDotOA(ZoneNum) * state.dataContaminantBalance->OutdoorCO2; + AA = thisZoneHB.VAMFL + thisZoneHB.EAMFL + thisZoneHB.CTMFL + thisZoneHB.MixingMassFlowZone + thisZoneHB.MDotOA; + BB = CO2Gain + ((thisZoneHB.VAMFL + thisZoneHB.EAMFL + thisZoneHB.CTMFL) * state.dataContaminantBalance->OutdoorCO2) + + state.dataContaminantBalance->MixingMassFlowCO2(ZoneNum) + thisZoneHB.MDotOA * state.dataContaminantBalance->OutdoorCO2; } Real64 CC = RhoAir * state.dataHeatBal->Zone(ZoneNum).Volume * state.dataHeatBal->Zone(ZoneNum).ZoneVolCapMultpCO2 / SysTimeStepInSeconds; @@ -2286,26 +2267,20 @@ void InverseModelCO2(EnergyPlusData &state, Real64 SumSysMxCO2_HM = state.dataHeatBal->Zone(ZoneNum).ZoneMeasuredSupplyAirFlowRate * state.dataHeatBal->Zone(ZoneNum).ZoneMeasuredSupplyAirCO2Concentration; - AA = SumSysM_HM + state.dataHeatBalFanSys->OAMFL(ZoneNum) + state.dataHeatBalFanSys->VAMFL(ZoneNum) + - state.dataHeatBalFanSys->EAMFL(ZoneNum) + state.dataHeatBalFanSys->CTMFL(ZoneNum) + - state.dataHeatBalFanSys->MixingMassFlowZone(ZoneNum) + state.dataHeatBalFanSys->MDotOA(ZoneNum); + AA = SumSysM_HM + thisZoneHB.OAMFL + thisZoneHB.VAMFL + thisZoneHB.EAMFL + thisZoneHB.CTMFL + thisZoneHB.MixingMassFlowZone + + thisZoneHB.MDotOA; BB = CO2GainExceptPeople + - ((state.dataHeatBalFanSys->OAMFL(ZoneNum) + state.dataHeatBalFanSys->VAMFL(ZoneNum) + state.dataHeatBalFanSys->EAMFL(ZoneNum) + - state.dataHeatBalFanSys->CTMFL(ZoneNum)) * - state.dataContaminantBalance->OutdoorCO2) + + ((thisZoneHB.OAMFL + thisZoneHB.VAMFL + thisZoneHB.EAMFL + thisZoneHB.CTMFL) * state.dataContaminantBalance->OutdoorCO2) + (SumSysMxCO2_HM) + state.dataContaminantBalance->MixingMassFlowCO2(ZoneNum) + - state.dataHeatBalFanSys->MDotOA(ZoneNum) * state.dataContaminantBalance->OutdoorCO2; + thisZoneHB.MDotOA * state.dataContaminantBalance->OutdoorCO2; } else { - AA = ZoneMassFlowRate + state.dataHeatBalFanSys->OAMFL(ZoneNum) + state.dataHeatBalFanSys->VAMFL(ZoneNum) + - state.dataHeatBalFanSys->EAMFL(ZoneNum) + state.dataHeatBalFanSys->CTMFL(ZoneNum) + - state.dataHeatBalFanSys->MixingMassFlowZone(ZoneNum) + state.dataHeatBalFanSys->MDotOA(ZoneNum); + AA = ZoneMassFlowRate + thisZoneHB.OAMFL + thisZoneHB.VAMFL + thisZoneHB.EAMFL + thisZoneHB.CTMFL + thisZoneHB.MixingMassFlowZone + + thisZoneHB.MDotOA; BB = CO2GainExceptPeople + - ((state.dataHeatBalFanSys->OAMFL(ZoneNum) + state.dataHeatBalFanSys->VAMFL(ZoneNum) + state.dataHeatBalFanSys->EAMFL(ZoneNum) + - state.dataHeatBalFanSys->CTMFL(ZoneNum)) * - state.dataContaminantBalance->OutdoorCO2) + + ((thisZoneHB.OAMFL + thisZoneHB.VAMFL + thisZoneHB.EAMFL + thisZoneHB.CTMFL) * state.dataContaminantBalance->OutdoorCO2) + (CO2MassFlowRate) + state.dataContaminantBalance->MixingMassFlowCO2(ZoneNum) + - state.dataHeatBalFanSys->MDotOA(ZoneNum) * state.dataContaminantBalance->OutdoorCO2; + thisZoneHB.MDotOA * state.dataContaminantBalance->OutdoorCO2; } Real64 CC = RhoAir * state.dataHeatBal->Zone(ZoneNum).Volume * state.dataHeatBal->Zone(ZoneNum).ZoneVolCapMultpCO2 / SysTimeStepInSeconds; @@ -2488,13 +2463,13 @@ void CorrectZoneContaminants(EnergyPlusData &state, } Real64 SysTimeStepInSeconds = DataGlobalConstants::SecInHour * state.dataHVACGlobal->TimeStepSys; + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); // Calculate the coefficients for the 3rd order derivative for final // zone humidity ratio. The A, B, C coefficients are analogous to the // CO2 balance. There are 2 cases that should be considered, system operating and system shutdown. - Real64 RhoAir = PsyRhoAirFnPbTdbW( - state, state.dataEnvrn->OutBaroPress, state.dataHeatBalFanSys->ZT(ZoneNum), state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum), RoutineName); + Real64 RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, thisZoneHB.ZT, thisZoneHB.ZoneAirHumRat, RoutineName); if (state.dataContaminantBalance->Contaminant.CO2Simulation) state.dataContaminantBalance->ZoneAirDensityCO(ZoneNum) = RhoAir; // Calculate Co2 internal gain @@ -2505,15 +2480,11 @@ void CorrectZoneContaminants(EnergyPlusData &state, GCGain = state.dataContaminantBalance->ZoneGCGain(ZoneNum) * RhoAir * 1.0e6; if (state.dataContaminantBalance->Contaminant.CO2Simulation) { - B = CO2Gain + - ((state.dataHeatBalFanSys->OAMFL(ZoneNum) + state.dataHeatBalFanSys->VAMFL(ZoneNum) + state.dataHeatBalFanSys->EAMFL(ZoneNum) + - state.dataHeatBalFanSys->CTMFL(ZoneNum)) * - state.dataContaminantBalance->OutdoorCO2) + + B = CO2Gain + ((thisZoneHB.OAMFL + thisZoneHB.VAMFL + thisZoneHB.EAMFL + thisZoneHB.CTMFL) * state.dataContaminantBalance->OutdoorCO2) + (CO2MassFlowRate) + state.dataContaminantBalance->MixingMassFlowCO2(ZoneNum) + - state.dataHeatBalFanSys->MDotOA(ZoneNum) * state.dataContaminantBalance->OutdoorCO2; - A = ZoneMassFlowRate + state.dataHeatBalFanSys->OAMFL(ZoneNum) + state.dataHeatBalFanSys->VAMFL(ZoneNum) + - state.dataHeatBalFanSys->EAMFL(ZoneNum) + state.dataHeatBalFanSys->CTMFL(ZoneNum) + - state.dataHeatBalFanSys->MixingMassFlowZone(ZoneNum) + state.dataHeatBalFanSys->MDotOA(ZoneNum); + thisZoneHB.MDotOA * state.dataContaminantBalance->OutdoorCO2; + A = ZoneMassFlowRate + thisZoneHB.OAMFL + thisZoneHB.VAMFL + thisZoneHB.EAMFL + thisZoneHB.CTMFL + thisZoneHB.MixingMassFlowZone + + thisZoneHB.MDotOA; if (state.afn->multizone_always_simulated || (state.afn->simulation_control.type == AirflowNetwork::ControlType::MultizoneWithDistributionOnlyDuringFanOperation && state.afn->AirflowNetworkFanActivated)) { @@ -2561,10 +2532,12 @@ void CorrectZoneContaminants(EnergyPlusData &state, if (zoneAirCO2Temp < 0.0) zoneAirCO2Temp = 0.0; state.dataContaminantBalance->ZoneAirCO2(ZoneNum) = zoneAirCO2Temp; - if ((state.dataHybridModel->HybridModelZone(ZoneNum).InfiltrationCalc_C || - state.dataHybridModel->HybridModelZone(ZoneNum).PeopleCountCalc_C) && - (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing)) { - InverseModelCO2(state, ZoneNum, CO2Gain, CO2GainExceptPeople, ZoneMassFlowRate, CO2MassFlowRate, RhoAir); + if (state.dataHybridModel->FlagHybridModel) { + if ((state.dataHybridModel->HybridModelZone(ZoneNum).InfiltrationCalc_C || + state.dataHybridModel->HybridModelZone(ZoneNum).PeopleCountCalc_C) && + (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing)) { + InverseModelCO2(state, ZoneNum, CO2Gain, CO2GainExceptPeople, ZoneMassFlowRate, CO2MassFlowRate, RhoAir); + } } // Now put the calculated info into the actual zone nodes; ONLY if there is zone air flow, i.e. controlled zone or plenum zone const int ZoneNodeNum = state.dataHeatBal->Zone(ZoneNum).SystemZoneNodeNumber; @@ -2574,15 +2547,11 @@ void CorrectZoneContaminants(EnergyPlusData &state, } if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) { - B = GCGain + - ((state.dataHeatBalFanSys->OAMFL(ZoneNum) + state.dataHeatBalFanSys->VAMFL(ZoneNum) + state.dataHeatBalFanSys->EAMFL(ZoneNum) + - state.dataHeatBalFanSys->CTMFL(ZoneNum)) * - state.dataContaminantBalance->OutdoorGC) + + B = GCGain + ((thisZoneHB.OAMFL + thisZoneHB.VAMFL + thisZoneHB.EAMFL + thisZoneHB.CTMFL) * state.dataContaminantBalance->OutdoorGC) + (GCMassFlowRate) + state.dataContaminantBalance->MixingMassFlowGC(ZoneNum) + - state.dataHeatBalFanSys->MDotOA(ZoneNum) * state.dataContaminantBalance->OutdoorGC; - A = ZoneMassFlowRate + state.dataHeatBalFanSys->OAMFL(ZoneNum) + state.dataHeatBalFanSys->VAMFL(ZoneNum) + - state.dataHeatBalFanSys->EAMFL(ZoneNum) + state.dataHeatBalFanSys->CTMFL(ZoneNum) + - state.dataHeatBalFanSys->MixingMassFlowZone(ZoneNum) + state.dataHeatBalFanSys->MDotOA(ZoneNum); + thisZoneHB.MDotOA * state.dataContaminantBalance->OutdoorGC; + A = ZoneMassFlowRate + thisZoneHB.OAMFL + thisZoneHB.VAMFL + thisZoneHB.EAMFL + thisZoneHB.CTMFL + thisZoneHB.MixingMassFlowZone + + thisZoneHB.MDotOA; if (state.afn->multizone_always_simulated || (state.afn->simulation_control.type == AirflowNetwork::ControlType::MultizoneWithDistributionOnlyDuringFanOperation && state.afn->AirflowNetworkFanActivated)) { diff --git a/src/EnergyPlus/ZoneContaminantPredictorCorrector.hh b/src/EnergyPlus/ZoneContaminantPredictorCorrector.hh index d3bcc1e378b..9954b8ca930 100644 --- a/src/EnergyPlus/ZoneContaminantPredictorCorrector.hh +++ b/src/EnergyPlus/ZoneContaminantPredictorCorrector.hh @@ -51,6 +51,7 @@ // EnergyPlus Headers #include #include +#include #include namespace EnergyPlus { diff --git a/src/EnergyPlus/ZoneEquipmentManager.cc b/src/EnergyPlus/ZoneEquipmentManager.cc index 6faec5ba7da..432ee95a180 100644 --- a/src/EnergyPlus/ZoneEquipmentManager.cc +++ b/src/EnergyPlus/ZoneEquipmentManager.cc @@ -223,16 +223,32 @@ void InitZoneEquipment(EnergyPlusData &state, bool const FirstHVACIteration) // if (state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).EquipListIndex == 0) continue; int ZoneEquipCount = state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).EquipListIndex).NumOfEquipTypes; - state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum).NumZoneEquipment = ZoneEquipCount; - state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum).SequencedOutputRequired.allocate(ZoneEquipCount); - state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum).SequencedOutputRequiredToHeatingSP.allocate(ZoneEquipCount); - state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum).SequencedOutputRequiredToCoolingSP.allocate(ZoneEquipCount); - state.dataZoneEnergyDemand->ZoneSysMoistureDemand(ControlledZoneNum).NumZoneEquipment = ZoneEquipCount; - state.dataZoneEnergyDemand->ZoneSysMoistureDemand(ControlledZoneNum).SequencedOutputRequired.allocate(ZoneEquipCount); - state.dataZoneEnergyDemand->ZoneSysMoistureDemand(ControlledZoneNum).SequencedOutputRequiredToHumidSP.allocate(ZoneEquipCount); - state.dataZoneEnergyDemand->ZoneSysMoistureDemand(ControlledZoneNum).SequencedOutputRequiredToDehumidSP.allocate(ZoneEquipCount); + auto &thisZoneSysEnergyDemand = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum); + thisZoneSysEnergyDemand.NumZoneEquipment = ZoneEquipCount; + thisZoneSysEnergyDemand.SequencedOutputRequired.allocate(ZoneEquipCount); + thisZoneSysEnergyDemand.SequencedOutputRequiredToHeatingSP.allocate(ZoneEquipCount); + thisZoneSysEnergyDemand.SequencedOutputRequiredToCoolingSP.allocate(ZoneEquipCount); + auto &thisZoneSysMoistureDemand = state.dataZoneEnergyDemand->ZoneSysMoistureDemand(ControlledZoneNum); + thisZoneSysMoistureDemand.NumZoneEquipment = ZoneEquipCount; + thisZoneSysMoistureDemand.SequencedOutputRequired.allocate(ZoneEquipCount); + thisZoneSysMoistureDemand.SequencedOutputRequiredToHumidSP.allocate(ZoneEquipCount); + thisZoneSysMoistureDemand.SequencedOutputRequiredToDehumidSP.allocate(ZoneEquipCount); state.dataSize->ZoneEqSizing(ControlledZoneNum).SizingMethod.allocate(DataHVACGlobals::NumOfSizingTypes); state.dataSize->ZoneEqSizing(ControlledZoneNum).SizingMethod = 0; + if (state.dataHeatBal->doSpaceHeatBalanceSimulation || state.dataHeatBal->doSpaceHeatBalanceSizing) { + for (int spaceNum : state.dataHeatBal->Zone(ControlledZoneNum).spaceIndexes) { + auto &thisSpaceSysEnergyDemand = state.dataZoneEnergyDemand->spaceSysEnergyDemand(spaceNum); + thisSpaceSysEnergyDemand.NumZoneEquipment = ZoneEquipCount; + thisSpaceSysEnergyDemand.SequencedOutputRequired.allocate(ZoneEquipCount); + thisSpaceSysEnergyDemand.SequencedOutputRequiredToHeatingSP.allocate(ZoneEquipCount); + thisSpaceSysEnergyDemand.SequencedOutputRequiredToCoolingSP.allocate(ZoneEquipCount); + auto &thisSpaceSysMoistureDemand = state.dataZoneEnergyDemand->spaceSysMoistureDemand(spaceNum); + thisSpaceSysMoistureDemand.NumZoneEquipment = ZoneEquipCount; + thisSpaceSysMoistureDemand.SequencedOutputRequired.allocate(ZoneEquipCount); + thisSpaceSysMoistureDemand.SequencedOutputRequiredToHumidSP.allocate(ZoneEquipCount); + thisSpaceSysMoistureDemand.SequencedOutputRequiredToDehumidSP.allocate(ZoneEquipCount); + } + } } } @@ -418,6 +434,7 @@ void SizeZoneEquipment(EnergyPlusData &state) for (int ControlledZoneNum = 1; ControlledZoneNum <= state.dataGlobal->NumOfZones; ++ControlledZoneNum) { auto &zoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum); + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ControlledZoneNum); if (!zoneEquipConfig.IsControlled) continue; // use reference to eliminate lots of long lines in this function, after initial commit, so reviewers can see changes @@ -426,8 +443,15 @@ void SizeZoneEquipment(EnergyPlusData &state) auto &zoneSysMoistureDemand = state.dataZoneEnergyDemand->ZoneSysMoistureDemand(ControlledZoneNum); auto &zone = state.dataHeatBal->Zone(ControlledZoneNum); - state.dataHeatBalFanSys->NonAirSystemResponse(ControlledZoneNum) = 0.0; - state.dataHeatBalFanSys->SysDepZoneLoads(ControlledZoneNum) = 0.0; + thisZoneHB.NonAirSystemResponse = 0.0; + thisZoneHB.SysDepZoneLoads = 0.0; + if (state.dataHeatBal->doSpaceHeatBalance) { + for (int spaceNum : state.dataHeatBal->Zone(ControlledZoneNum).spaceIndexes) { + // SpaceHB ToDo: For now allocate by space volume frac + state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).NonAirSystemResponse = 0.0; + state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).SysDepZoneLoads = 0.0; + } + } SysOutputProvided = 0.0; LatOutputProvided = 0.0; InitSystemOutputRequired(state, ControlledZoneNum, true); @@ -649,10 +673,17 @@ void SizeZoneEquipment(EnergyPlusData &state) Node(SupplyAirNode).Enthalpy = Enthalpy; Node(SupplyAirNode).MassFlowRate = MassFlowRate; } else { - state.dataHeatBalFanSys->NonAirSystemResponse(ControlledZoneNum) = SysOutputProvided; + thisZoneHB.NonAirSystemResponse = SysOutputProvided; + if (state.dataHeatBal->doSpaceHeatBalance) { + for (int spaceNum : state.dataHeatBal->Zone(ControlledZoneNum).spaceIndexes) { + // SpaceHB ToDo: For now allocate by space volume frac + state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).NonAirSystemResponse = + thisZoneHB.NonAirSystemResponse * state.dataHeatBal->space(spaceNum).fracZoneVolume; + } + } if (calcZoneSizing.zoneLatentSizing) { int ZoneMult = zone.Multiplier * zone.ListMultiplier; - state.dataHeatBalFanSys->ZoneLatentGain(ControlledZoneNum) += (LatOutputProvided * HgAir) / ZoneMult; + thisZoneHB.ZoneLatentGain += (LatOutputProvided * HgAir) / ZoneMult; } } @@ -3181,9 +3212,10 @@ void SimZoneEquipment(EnergyPlusData &state, bool const FirstHVACIteration, bool for (int ControlledZoneNum = 1; ControlledZoneNum <= state.dataGlobal->NumOfZones; ++ControlledZoneNum) { if (!state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).IsControlled) continue; + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ControlledZoneNum); - state.dataHeatBalFanSys->NonAirSystemResponse(ControlledZoneNum) = 0.0; - state.dataHeatBalFanSys->SysDepZoneLoads(ControlledZoneNum) = 0.0; + thisZoneHB.NonAirSystemResponse = 0.0; + thisZoneHB.SysDepZoneLoads = 0.0; auto &zoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum); zoneEquipConfig.ZoneExh = 0.0; zoneEquipConfig.ZoneExhBalanced = 0.0; @@ -3298,7 +3330,7 @@ void SimZoneEquipment(EnergyPlusData &state, bool const FirstHVACIteration, bool TurnZoneFansOnlyOn = false; TurnFansOff = false; - state.dataHeatBalFanSys->NonAirSystemResponse(ControlledZoneNum) += NonAirSysOutput; + thisZoneHB.NonAirSystemResponse += NonAirSysOutput; SysOutputProvided = NonAirSysOutput + AirSysOutput; } break; case ZoneEquip::VRFTerminalUnit: { // 'ZoneHVAC:TerminalUnit:VariableRefrigerantFlow' @@ -3361,7 +3393,7 @@ void SimZoneEquipment(EnergyPlusData &state, bool const FirstHVACIteration, bool LatOutputProvided, zoneEquipList.EquipIndex(EquipPtr)); - state.dataHeatBalFanSys->SysDepZoneLoads(ControlledZoneNum) += SysOutputProvided; + thisZoneHB.SysDepZoneLoads += SysOutputProvided; SysOutputProvided = 0.0; // Reset to 0.0 since this equipment is controlled based on zone humidity level (not // temperature) SysOutputProvided amount was already sent above to @@ -3411,7 +3443,7 @@ void SimZoneEquipment(EnergyPlusData &state, bool const FirstHVACIteration, bool SysOutputProvided, zoneEquipList.EquipIndex(EquipPtr)); - state.dataHeatBalFanSys->NonAirSystemResponse(ControlledZoneNum) += SysOutputProvided; + thisZoneHB.NonAirSystemResponse += SysOutputProvided; LatOutputProvided = 0.0; // This baseboard does not add/remove any latent heat } break; case ZoneEquip::BBSteam: { // 'ZoneHVAC:Baseboard:RadiantConvective:Steam' @@ -3422,7 +3454,7 @@ void SimZoneEquipment(EnergyPlusData &state, bool const FirstHVACIteration, bool SysOutputProvided, zoneEquipList.EquipIndex(EquipPtr)); - state.dataHeatBalFanSys->NonAirSystemResponse(ControlledZoneNum) += SysOutputProvided; + thisZoneHB.NonAirSystemResponse += SysOutputProvided; LatOutputProvided = 0.0; // This baseboard does not add/remove any latent heat } break; case ZoneEquip::BBWaterConvective: { // 'ZoneHVAC:Baseboard:Convective:Water' @@ -3433,7 +3465,7 @@ void SimZoneEquipment(EnergyPlusData &state, bool const FirstHVACIteration, bool SysOutputProvided, zoneEquipList.EquipIndex(EquipPtr)); - state.dataHeatBalFanSys->NonAirSystemResponse(ControlledZoneNum) += SysOutputProvided; + thisZoneHB.NonAirSystemResponse += SysOutputProvided; LatOutputProvided = 0.0; // This baseboard does not add/remove any latent heat } break; case ZoneEquip::BBElectricConvective: { // 'ZoneHVAC:Baseboard:Convective:Electric' @@ -3443,7 +3475,7 @@ void SimZoneEquipment(EnergyPlusData &state, bool const FirstHVACIteration, bool SysOutputProvided, zoneEquipList.EquipIndex(EquipPtr)); - state.dataHeatBalFanSys->NonAirSystemResponse(ControlledZoneNum) += SysOutputProvided; + thisZoneHB.NonAirSystemResponse += SysOutputProvided; LatOutputProvided = 0.0; // This baseboard does not add/remove any latent heat } break; case ZoneEquip::CoolingPanel: { // 'ZoneHVAC:CoolingPanel:RadiantConvective:Water' @@ -3454,7 +3486,7 @@ void SimZoneEquipment(EnergyPlusData &state, bool const FirstHVACIteration, bool SysOutputProvided, zoneEquipList.EquipIndex(EquipPtr)); - state.dataHeatBalFanSys->NonAirSystemResponse(ControlledZoneNum) += SysOutputProvided; + thisZoneHB.NonAirSystemResponse += SysOutputProvided; LatOutputProvided = 0.0; // This cooling panel does not add/remove any latent heat } break; case ZoneEquip::HiTempRadiant: { // 'ZoneHVAC:HighTemperatureRadiant' @@ -3547,7 +3579,7 @@ void SimZoneEquipment(EnergyPlusData &state, bool const FirstHVACIteration, bool SysOutputProvided, zoneEquipList.EquipIndex(EquipPtr)); - state.dataHeatBalFanSys->NonAirSystemResponse(ControlledZoneNum) += SysOutputProvided; + thisZoneHB.NonAirSystemResponse += SysOutputProvided; LatOutputProvided = 0.0; // This baseboard does not add/remove any latent heat } break; case ZoneEquip::RefrigerationAirChillerSet: { // 'ZoneHVAC:RefrigerationChillerSet' @@ -3559,7 +3591,7 @@ void SimZoneEquipment(EnergyPlusData &state, bool const FirstHVACIteration, bool LatOutputProvided, zoneEquipList.EquipIndex(EquipPtr)); - state.dataHeatBalFanSys->NonAirSystemResponse(ControlledZoneNum) += SysOutputProvided; + thisZoneHB.NonAirSystemResponse += SysOutputProvided; } break; case ZoneEquip::UserDefinedZoneHVACForcedAir: { UserDefinedComponents::SimZoneAirUserDefined(state, @@ -3607,8 +3639,15 @@ void SimZoneEquipment(EnergyPlusData &state, bool const FirstHVACIteration, bool UpdateSystemOutputRequired(state, ControlledZoneNum, SysOutputProvided, LatOutputProvided, EquipTypeNum); state.dataSize->CurTermUnitSizingNum = 0; - } // zone loop - } // End of controlled zone loop + } // zone equipment loop + if (state.dataHeatBal->doSpaceHeatBalance) { + for (int spaceNum : state.dataHeatBal->Zone(ControlledZoneNum).spaceIndexes) { + // SpaceHB ToDo: For now allocate by space volume frac + state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).NonAirSystemResponse = + thisZoneHB.NonAirSystemResponse * state.dataHeatBal->space(spaceNum).fracZoneVolume; + } + } + } // End of controlled zone loop state.dataSize->CurZoneEqNum = 0; state.dataZoneEquipmentManager->FirstPassZoneEquipFlag = false; @@ -3747,10 +3786,36 @@ void InitSystemOutputRequired(EnergyPlusData &state, int const ZoneNum, bool con // METHODOLOGY EMPLOYED: // Initialize remaining output variables using predictor calculations + initOutputRequired(state, + ZoneNum, + state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum), + state.dataZoneEnergyDemand->ZoneSysMoistureDemand(ZoneNum), + FirstHVACIteration, + ResetSimOrder); + // SpaceHB TODO: This may need more work + if (state.dataHeatBal->doSpaceHeatBalance) { + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + initOutputRequired(state, + ZoneNum, + state.dataZoneEnergyDemand->spaceSysEnergyDemand(spaceNum), + state.dataZoneEnergyDemand->spaceSysMoistureDemand(spaceNum), + FirstHVACIteration, + ResetSimOrder, + spaceNum); + } + } - auto &energy(state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum)); - auto &moisture(state.dataZoneEnergyDemand->ZoneSysMoistureDemand(ZoneNum)); + DistributeSystemOutputRequired(state, ZoneNum, FirstHVACIteration); +} +void initOutputRequired(EnergyPlusData &state, + int const ZoneNum, + DataZoneEnergyDemands::ZoneSystemSensibleDemand &energy, + DataZoneEnergyDemands::ZoneSystemMoistureDemand &moisture, + bool const FirstHVACIteration, + bool const ResetSimOrder, + int spaceNum) +{ energy.RemainingOutputRequired = energy.TotalOutputRequired; energy.UnadjRemainingOutputRequired = energy.TotalOutputRequired; energy.RemainingOutputReqToHeatSP = energy.OutputRequiredToHeatingSP; @@ -3765,7 +3830,7 @@ void InitSystemOutputRequired(EnergyPlusData &state, int const ZoneNum, bool con moisture.RemainingOutputReqToDehumidSP = moisture.OutputRequiredToDehumidifyingSP; moisture.UnadjRemainingOutputReqToDehumidSP = moisture.OutputRequiredToDehumidifyingSP; - if (ResetSimOrder) { + if (ResetSimOrder && spaceNum == 0) { SetZoneEquipSimOrder(state, ZoneNum); } @@ -3795,6 +3860,7 @@ void InitSystemOutputRequired(EnergyPlusData &state, int const ZoneNum, bool con } else if ((loadDistType == DataZoneEquipment::LoadDist::UniformPLR) || (loadDistType == DataZoneEquipment::LoadDist::SequentialUniformPLR)) { // init each sequenced demand to the zone design load in order to get available capacities from equipment + // SpaceHB TODO: This may need more work if (energy.TotalOutputRequired >= 0.0) { energy.SequencedOutputRequired = state.dataSize->FinalZoneSizing(ZoneNum).DesHeatLoad; // array assignment } else { @@ -3828,8 +3894,6 @@ void InitSystemOutputRequired(EnergyPlusData &state, int const ZoneNum, bool con } state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum) = state.dataZoneEnergyDemand->DeadBandOrSetback(ZoneNum); - - DistributeSystemOutputRequired(state, ZoneNum, FirstHVACIteration); } void DistributeSystemOutputRequired(EnergyPlusData &state, int const ZoneNum, bool const FirstHVACIteration) @@ -3846,8 +3910,24 @@ void DistributeSystemOutputRequired(EnergyPlusData &state, int const ZoneNum, bo return; } - auto &energy(state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum)); - auto &moisture(state.dataZoneEnergyDemand->ZoneSysMoistureDemand(ZoneNum)); + distributeOutputRequired( + state, ZoneNum, state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum), state.dataZoneEnergyDemand->ZoneSysMoistureDemand(ZoneNum)); + // SpaceHB TODO: This may need more work + if (state.dataHeatBal->doSpaceHeatBalance) { + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + distributeOutputRequired(state, + ZoneNum, + state.dataZoneEnergyDemand->spaceSysEnergyDemand(spaceNum), + state.dataZoneEnergyDemand->spaceSysMoistureDemand(spaceNum)); + } + } +} + +void distributeOutputRequired(EnergyPlusData &state, + int const ZoneNum, + DataZoneEnergyDemands::ZoneSystemSensibleDemand &energy, + DataZoneEnergyDemands::ZoneSystemMoistureDemand &moisture) +{ auto &thisZEqList(state.dataZoneEquip->ZoneEquipList(ZoneNum)); Real64 heatLoadRatio = 1.0; Real64 coolLoadRatio = 1.0; @@ -4451,7 +4531,7 @@ void CalcZoneMassBalance(EnergyPlusData &state, bool const FirstHVACIteration) // Set zone mixing incoming mass flow rate if ((Iteration == 0) || state.dataHeatBal->ZoneAirMassFlow.ZoneFlowAdjustment == DataHeatBalance::AdjustmentType::AdjustReturnOnly || state.dataHeatBal->ZoneAirMassFlow.ZoneFlowAdjustment == DataHeatBalance::AdjustmentType::AdjustReturnThenMixing) { - ZoneMixingAirMassFlowRate = state.dataHeatBalFanSys->MixingMassFlowZone(ZoneNum); + ZoneMixingAirMassFlowRate = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MixingMassFlowZone; } else { ZoneMixingAirMassFlowRate = max(0.0, ZoneReturnAirMassFlowRate + TotExhaustAirMassFlowRate - TotInletAirMassFlowRate + @@ -4579,6 +4659,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); if (!thisZoneEquip.IsControlled) continue; int numRetNodes = thisZoneEquip.NumReturnNodes; Real64 totalZoneReturnMassFlow = 0.0; @@ -4603,8 +4684,7 @@ void CalcZoneMassBalance(EnergyPlusData &state, bool const FirstHVACIteration) Real64 sysUnbalancedFlow = sysUnbalExhaust + totalZoneReturnMassFlow - thisZoneEquip.TotInletAirMassFlowRate; if (sysUnbalancedFlow > DataHVACGlobals::SmallMassFlow) { // Now include infiltration, ventilation, and mixing flows (these are all entering the zone, so subtract them) - Real64 incomingFlow = state.dataHeatBalFanSys->OAMFL(zoneNum) + state.dataHeatBalFanSys->VAMFL(zoneNum) + - state.dataHeatBalFanSys->MixingMassFlowZone(zoneNum); + Real64 incomingFlow = thisZoneHB.OAMFL + thisZoneHB.VAMFL + thisZoneHB.MixingMassFlowZone; Real64 unbalancedFlow = max(0.0, sysUnbalancedFlow - incomingFlow); if (unbalancedFlow > DataHVACGlobals::SmallMassFlow) { // Re-check on volume basis - use current zone density for incoming, standard density for HVAC sys @@ -4626,9 +4706,9 @@ void CalcZoneMassBalance(EnergyPlusData &state, bool const FirstHVACIteration) totalZoneReturnMassFlow / state.dataEnvrn->StdRhoAir)); ShowContinueError(state, format(" Infiltration: {:.6R} Zone Ventilation: {:.6R} Mixing (incoming): {:.6R}", - state.dataHeatBalFanSys->OAMFL(zoneNum) / rhoZone, - state.dataHeatBalFanSys->VAMFL(zoneNum) / rhoZone, - state.dataHeatBalFanSys->MixingMassFlowZone(zoneNum) / rhoZone)); + thisZoneHB.OAMFL / rhoZone, + thisZoneHB.VAMFL / rhoZone, + thisZoneHB.MixingMassFlowZone / rhoZone)); ShowContinueError( state, format(" Imbalance (excess outflow): {:.6R} Total system OA flow (for all airloops serving this zone): {:.6R}", @@ -4926,13 +5006,14 @@ void CalcZoneLeavingConditions(EnergyPlusData &state, bool const FirstHVACIterat if (state.dataZoneEquip->ZoneEquipConfig(ZoneNum).NumReturnNodes == 0) continue; int ZoneNode = state.dataZoneEquip->ZoneEquipConfig(ZoneNum).ZoneNode; int ZoneMult = state.dataHeatBal->Zone(ZoneNum).Multiplier * state.dataHeatBal->Zone(ZoneNum).ListMultiplier; + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); for (int nodeCount = 1; nodeCount <= state.dataZoneEquip->ZoneEquipConfig(ZoneNum).NumReturnNodes; ++nodeCount) { int ReturnNode = state.dataZoneEquip->ZoneEquipConfig(ZoneNum).ReturnNode(nodeCount); int ReturnNodeExhaustNum = state.dataZoneEquip->ZoneEquipConfig(ZoneNum).ReturnNodeExhaustNodeNum(nodeCount); // RETURN AIR HEAT GAIN from the Lights statement; this heat gain is stored in // Add sensible heat gain from refrigerated cases with under case returns - Real64 QRetAir = InternalHeatGains::SumAllReturnAirConvectionGains(state, ZoneNum, ReturnNode); + Real64 QRetAir = InternalHeatGains::zoneSumAllReturnAirConvectionGains(state, ZoneNum, ReturnNode); // Need to add the energy to the return air from lights and from airflow windows. Where the heat // is added depends on if there is system flow or not. If there is system flow the heat is added @@ -4963,17 +5044,19 @@ void CalcZoneLeavingConditions(EnergyPlusData &state, bool const FirstHVACIterat Real64 WinGapFlowTtoRA = 0.0; // Sum of mass flow times outlet temp for all airflow windows in zone [(kg/s)-C] if (state.dataHeatBal->Zone(ZoneNum).HasAirFlowWindowReturn) { - for (int SurfNum = state.dataHeatBal->Zone(ZoneNum).HTSurfaceFirst; SurfNum <= state.dataHeatBal->Zone(ZoneNum).HTSurfaceLast; - ++SurfNum) { - if (state.dataSurface->SurfWinAirflowThisTS(SurfNum) > 0.0 && - state.dataSurface->SurfWinAirflowDestination(SurfNum) == DataSurfaces::WindowAirFlowDestination::Return) { - Real64 FlowThisTS = PsyRhoAirFnPbTdbW(state, - state.dataEnvrn->OutBaroPress, - state.dataSurface->SurfWinTAirflowGapOutlet(SurfNum), - state.dataLoopNodes->Node(ZoneNode).HumRat) * - state.dataSurface->SurfWinAirflowThisTS(SurfNum) * state.dataSurface->Surface(SurfNum).Width; - WinGapFlowToRA += FlowThisTS; - WinGapFlowTtoRA += FlowThisTS * state.dataSurface->SurfWinTAirflowGapOutlet(SurfNum); + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &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) { + Real64 FlowThisTS = PsyRhoAirFnPbTdbW(state, + state.dataEnvrn->OutBaroPress, + state.dataSurface->SurfWinTAirflowGapOutlet(SurfNum), + state.dataLoopNodes->Node(ZoneNode).HumRat) * + state.dataSurface->SurfWinAirflowThisTS(SurfNum) * state.dataSurface->Surface(SurfNum).Width; + WinGapFlowToRA += FlowThisTS; + WinGapFlowTtoRA += FlowThisTS * state.dataSurface->SurfWinTAirflowGapOutlet(SurfNum); + } } } } @@ -4992,7 +5075,7 @@ void CalcZoneLeavingConditions(EnergyPlusData &state, bool const FirstHVACIterat // All of return air comes from flow through airflow windows TempRetAir = WinGapTtoRA; // Put heat from window airflow that exceeds return air flow into zone air - state.dataHeatBalFanSys->SysDepZoneLoads(ZoneNum) += (WinGapFlowToRA - MassFlowRA) * CpAir * (WinGapTtoRA - TempZoneAir); + thisZoneHB.SysDepZoneLoads += (WinGapFlowToRA - MassFlowRA) * CpAir * (WinGapTtoRA - TempZoneAir); } } // Add heat-to-return from lights @@ -5000,12 +5083,12 @@ void CalcZoneLeavingConditions(EnergyPlusData &state, bool const FirstHVACIterat if (TempRetAir > DataHVACGlobals::RetTempMax) { state.dataLoopNodes->Node(ReturnNode).Temp = DataHVACGlobals::RetTempMax; if (!state.dataGlobal->ZoneSizingCalc) { - state.dataHeatBalFanSys->SysDepZoneLoads(ZoneNum) += CpAir * MassFlowRA * (TempRetAir - DataHVACGlobals::RetTempMax); + thisZoneHB.SysDepZoneLoads += CpAir * MassFlowRA * (TempRetAir - DataHVACGlobals::RetTempMax); } } else if (TempRetAir < DataHVACGlobals::RetTempMin) { state.dataLoopNodes->Node(ReturnNode).Temp = DataHVACGlobals::RetTempMin; if (!state.dataGlobal->ZoneSizingCalc) { - state.dataHeatBalFanSys->SysDepZoneLoads(ZoneNum) += CpAir * MassFlowRA * (TempRetAir - DataHVACGlobals::RetTempMin); + thisZoneHB.SysDepZoneLoads += CpAir * MassFlowRA * (TempRetAir - DataHVACGlobals::RetTempMin); } } else { state.dataLoopNodes->Node(ReturnNode).Temp = TempRetAir; @@ -5019,10 +5102,9 @@ void CalcZoneLeavingConditions(EnergyPlusData &state, bool const FirstHVACIterat } } else { // No return air flow // Assign all heat-to-return from window gap airflow to zone air - if (WinGapFlowToRA > 0.0) - state.dataHeatBalFanSys->SysDepZoneLoads(ZoneNum) += WinGapFlowToRA * CpAir * (WinGapTtoRA - TempZoneAir); + if (WinGapFlowToRA > 0.0) thisZoneHB.SysDepZoneLoads += WinGapFlowToRA * CpAir * (WinGapTtoRA - TempZoneAir); // Assign all heat-to-return from lights to zone air - if (QRetAir > 0.0) state.dataHeatBalFanSys->SysDepZoneLoads(ZoneNum) += QRetAir; + if (QRetAir > 0.0) thisZoneHB.SysDepZoneLoads += QRetAir; state.dataLoopNodes->Node(ReturnNode).Temp = state.dataLoopNodes->Node(ZoneNode).Temp; } } else { @@ -5047,14 +5129,14 @@ void CalcZoneLeavingConditions(EnergyPlusData &state, bool const FirstHVACIterat state.dataHeatBal->RefrigCaseCredit(ZoneNum).LatCaseCreditToHVAC; // shouldn't the HVAC term be zeroed out then? SumRetAirLatentGainRate = InternalHeatGains::SumAllReturnAirLatentGains(state, ZoneNum, ReturnNode); - state.dataHeatBalFanSys->ZoneLatentGain(ZoneNum) += SumRetAirLatentGainRate; + thisZoneHB.ZoneLatentGain += SumRetAirLatentGainRate; } } else { state.dataLoopNodes->Node(ReturnNode).HumRat = state.dataLoopNodes->Node(ZoneNode).HumRat; state.dataHeatBal->RefrigCaseCredit(ZoneNum).LatCaseCreditToZone += state.dataHeatBal->RefrigCaseCredit(ZoneNum).LatCaseCreditToHVAC; // shouldn't the HVAC term be zeroed out then? SumRetAirLatentGainRate = InternalHeatGains::SumAllReturnAirLatentGains(state, ZoneNum, ReturnNode); - state.dataHeatBalFanSys->ZoneLatentGain(ZoneNum) += SumRetAirLatentGainRate; + thisZoneHB.ZoneLatentGain += SumRetAirLatentGainRate; } state.dataLoopNodes->Node(ReturnNode).Enthalpy = @@ -5103,7 +5185,6 @@ void CalcAirFlowSimple(EnergyPlusData &state, bool const AdjustZoneInfiltrationFlowFlag // holds zone mixing air flow calc status ) { - // SUBROUTINE INFORMATION: // AUTHOR Legacy Code // MODIFIED Shirey, Jan 2008 (MIXING objects, use avg. conditions for Cp, Air Density and Hfg) @@ -5118,85 +5199,50 @@ void CalcAirFlowSimple(EnergyPlusData &state, // PURPOSE OF THIS SUBROUTINE: // This subroutine calculates the air component of the heat balance. - // Using/Aliasing - using namespace DataHeatBalFanSys; - using namespace DataHeatBalance; - using CoolTower::ManageCoolTower; - using DataHVACGlobals::CycleOn; - using DataHVACGlobals::CycleOnZoneFansOnly; - auto &TimeStepSys = state.dataHVACGlobal->TimeStepSys; - using EarthTube::ManageEarthTube; - using Psychrometrics::PsyCpAirFnW; - using Psychrometrics::PsyRhoAirFnPbTdbW; - using Psychrometrics::PsyTdbFnHW; - using Psychrometrics::PsyWFnTdbTwbPb; - using ScheduleManager::GetCurrentScheduleValue; - using ThermalChimney::ManageThermalChimney; - using namespace DataLoopNode; - - // SUBROUTINE PARAMETER DEFINITIONS: constexpr Real64 StdGravity(9.80665); // The acceleration of gravity at the sea level (m/s2) + static constexpr std::string_view RoutineNameVentilation("CalcAirFlowSimple:Ventilation"); static constexpr std::string_view RoutineNameMixing("CalcAirFlowSimple:Mixing"); static constexpr std::string_view RoutineNameCrossMixing("CalcAirFlowSimple:CrossMixing"); static constexpr std::string_view RoutineNameRefrigerationDoorMixing("CalcAirFlowSimple:RefrigerationDoorMixing"); static constexpr std::string_view RoutineNameInfiltration("CalcAirFlowSimple:Infiltration"); static constexpr std::string_view RoutineNameZoneAirBalance("CalcAirFlowSimple:ZoneAirBalance"); - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - Real64 MCP; - Real64 MCPxM; - Real64 MCPxN; - Real64 TZM; // Temperature of From Zone - Real64 TZN; // Temperature of this zone - Real64 TD; // Delta Temp limit of Mixing statement - int m; // Index to From Zone - int n; // Index of this zone - int I; // Ventilation master object index - int NH; // Hybrid controlled zone number - Real64 AirDensity; // Density of air (kg/m^3) - Real64 CpAir; // Heat capacity of air (J/kg-C) - Real64 OutletAirEnthalpy; // Enthlapy of outlet air (VENTILATION objects) - Real64 HumRatExt; - Real64 EnthalpyExt; - bool MixingLimitFlag; - Real64 MixingTmin; - Real64 MixingTmax; - - Real64 MCpI_temp; - Real64 VAMFL_temp; - - Real64 Cw; // Opening effectivenss - Real64 Cd; // Discharge coefficent - Real64 angle; // Angle between wind direction and effective angle - Real64 Qw; // Volumetric flow driven by wind - Real64 Qst; // Volumetric flow driven by stack effect - // following variables used for refrigeration door mixing and all defined in EngRef - Real64 MassFlowDryAir; - Real64 FDens; - Real64 Fb; - - // Allocate the ZMAT and ZHumRat arrays - - if (!allocated(state.dataZoneEquip->ZMAT)) state.dataZoneEquip->ZMAT.allocate(state.dataGlobal->NumOfZones); - if (!allocated(state.dataZoneEquip->ZHumRat)) state.dataZoneEquip->ZHumRat.allocate(state.dataGlobal->NumOfZones); - if (!allocated(state.dataZoneEquip->VentMCP)) state.dataZoneEquip->VentMCP.allocate(state.dataHeatBal->TotVentilation); - - // Allocate module level logical arrays for MIXING and CROSS MIXING reporting - if (!allocated(state.dataZoneEquip->CrossMixingReportFlag)) - state.dataZoneEquip->CrossMixingReportFlag.allocate(state.dataHeatBal->TotCrossMixing); - if (!allocated(state.dataZoneEquip->MixingReportFlag)) state.dataZoneEquip->MixingReportFlag.allocate(state.dataHeatBal->TotMixing); - - if (!allocated(state.dataHeatBalFanSys->MCPTThermChim)) state.dataHeatBalFanSys->MCPTThermChim.allocate(state.dataGlobal->NumOfZones); - if (!allocated(state.dataHeatBalFanSys->MCPThermChim)) state.dataHeatBalFanSys->MCPThermChim.allocate(state.dataGlobal->NumOfZones); - if (!allocated(state.dataHeatBalFanSys->ThermChimAMFL)) state.dataHeatBalFanSys->ThermChimAMFL.allocate(state.dataGlobal->NumOfZones); - - // COMPUTE ZONE AIR MIXINGS - state.dataHeatBalFanSys->MCPM = 0.0; - state.dataHeatBalFanSys->MCPTM = 0.0; - state.dataHeatBalFanSys->MixingMassFlowZone = 0.0; - state.dataHeatBalFanSys->MixingMassFlowXHumRat = 0.0; - state.dataZoneEquip->CrossMixingReportFlag = false; - state.dataZoneEquip->MixingReportFlag = false; + for (auto &thisZoneHB : state.dataZoneTempPredictorCorrector->zoneHeatBalance) { + thisZoneHB.MCPM = 0.0; + thisZoneHB.MCPTM = 0.0; + thisZoneHB.MCPTI = 0.0; + thisZoneHB.MCPI = 0.0; + thisZoneHB.OAMFL = 0.0; + thisZoneHB.MCPTV = 0.0; + thisZoneHB.MCPV = 0.0; + thisZoneHB.VAMFL = 0.0; + thisZoneHB.MDotCPOA = 0.0; + thisZoneHB.MDotOA = 0.0; + thisZoneHB.MCPThermChim = 0.0; + thisZoneHB.ThermChimAMFL = 0.0; + thisZoneHB.MCPTThermChim = 0.0; + thisZoneHB.MixingMassFlowZone = 0.0; + thisZoneHB.MixingMassFlowXHumRat = 0.0; + } + if (state.dataHeatBal->doSpaceHeatBalance) { + for (auto &thisSpaceHB : state.dataZoneTempPredictorCorrector->spaceHeatBalance) { + thisSpaceHB.MCPM = 0.0; + thisSpaceHB.MCPTM = 0.0; + thisSpaceHB.MCPTI = 0.0; + thisSpaceHB.MCPI = 0.0; + thisSpaceHB.OAMFL = 0.0; + thisSpaceHB.MCPTV = 0.0; + thisSpaceHB.MCPV = 0.0; + thisSpaceHB.VAMFL = 0.0; + thisSpaceHB.MDotCPOA = 0.0; + thisSpaceHB.MDotOA = 0.0; + thisSpaceHB.MCPThermChim = 0.0; + thisSpaceHB.ThermChimAMFL = 0.0; + thisSpaceHB.MCPTThermChim = 0.0; + thisSpaceHB.MixingMassFlowZone = 0.0; + thisSpaceHB.MixingMassFlowXHumRat = 0.0; + } + } if (state.dataContaminantBalance->Contaminant.CO2Simulation && state.dataHeatBal->TotMixing + state.dataHeatBal->TotCrossMixing + state.dataHeatBal->TotRefDoorMixing > 0) state.dataContaminantBalance->MixingMassFlowCO2 = 0.0; @@ -5205,19 +5251,7 @@ void CalcAirFlowSimple(EnergyPlusData &state, state.dataContaminantBalance->MixingMassFlowGC = 0.0; Real64 IVF = 0.0; // DESIGN INFILTRATION FLOW RATE (M**3/SEC) - state.dataHeatBalFanSys->MCPTI = 0.0; - state.dataHeatBalFanSys->MCPI = 0.0; - state.dataHeatBalFanSys->OAMFL = 0.0; Real64 VVF = 0.0; // DESIGN VENTILATION FLOW RATE (M**3/SEC) - state.dataHeatBalFanSys->MCPTV = 0.0; - state.dataHeatBalFanSys->MCPV = 0.0; - state.dataHeatBalFanSys->VAMFL = 0.0; - state.dataZoneEquip->VentMCP = 0.0; - state.dataHeatBalFanSys->MDotCPOA = 0.0; - state.dataHeatBalFanSys->MDotOA = 0.0; - state.dataHeatBalFanSys->MCPThermChim = 0.0; - state.dataHeatBalFanSys->ThermChimAMFL = 0.0; - state.dataHeatBalFanSys->MCPTThermChim = 0.0; if (!state.dataHeatBal->AirFlowFlag) return; // AirflowNetwork Multizone field /= SIMPLE @@ -5226,25 +5260,29 @@ void CalcAirFlowSimple(EnergyPlusData &state, return; } - ManageEarthTube(state); - ManageCoolTower(state); - ManageThermalChimney(state); + EarthTube::ManageEarthTube(state); + CoolTower::ManageCoolTower(state); + ThermalChimney::ManageThermalChimney(state); // Assign zone air temperature - for (int j = 1; j <= state.dataGlobal->NumOfZones; ++j) { - state.dataZoneEquip->ZMAT(j) = state.dataHeatBalFanSys->MAT(j); - state.dataZoneEquip->ZHumRat(j) = state.dataHeatBalFanSys->ZoneAirHumRat(j); + for (auto &thisZoneHB : state.dataZoneTempPredictorCorrector->zoneHeatBalance) { + thisZoneHB.MixingMAT = thisZoneHB.MAT; + thisZoneHB.MixingHumRat = thisZoneHB.ZoneAirHumRat; // This is only temporary fix for CR8867. (L. Gu 8/12) if (SysTimestepLoop == 1) { - state.dataZoneEquip->ZMAT(j) = state.dataHeatBalFanSys->XMPT(j); - state.dataZoneEquip->ZHumRat(j) = state.dataHeatBalFanSys->WZoneTimeMinusP(j); + thisZoneHB.MixingMAT = thisZoneHB.XMPT; + thisZoneHB.MixingHumRat = thisZoneHB.WZoneTimeMinusP; } } - - // Process the scheduled Ventilation for air heat balance - if (state.dataHeatBal->TotVentilation > 0) { - for (auto &e : state.dataHeatBal->ZnAirRpt) { - e.VentilFanElec = 0.0; + if (state.dataHeatBal->doSpaceHeatBalance) { + for (auto &thisSpaceHB : state.dataZoneTempPredictorCorrector->spaceHeatBalance) { + thisSpaceHB.MixingMAT = thisSpaceHB.MAT; + thisSpaceHB.MixingHumRat = thisSpaceHB.ZoneAirHumRat; + // This is only temporary fix for CR8867. (L. Gu 8/12) + if (SysTimestepLoop == 1) { + thisSpaceHB.MixingMAT = thisSpaceHB.XMPT; + thisSpaceHB.MixingHumRat = thisSpaceHB.WZoneTimeMinusP; + } } } @@ -5260,367 +5298,415 @@ void CalcAirFlowSimple(EnergyPlusData &state, } } + if (state.dataHeatBal->TotVentilation > 0) { + for (auto &e : state.dataHeatBal->ZnAirRpt) { + e.VentilFanElec = 0.0; + } + } + + // Process the scheduled Ventilation for air heat balance for (int j = 1; j <= state.dataHeatBal->TotVentilation; ++j) { + auto &thisVentilation = state.dataHeatBal->Ventilation(j); + int zoneNum = thisVentilation.ZonePtr; + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum); + Real64 thisMixingMAT = 0.0; + if (state.dataHeatBal->doSpaceHeatBalance) { + thisMixingMAT = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisVentilation.spaceIndex).MixingMAT; + } else { + thisMixingMAT = thisZoneHB.MixingMAT; + } + thisVentilation.FanPower = 0.0; + thisVentilation.MCP = 0.0; + + Real64 TempExt = state.dataHeatBal->Zone(zoneNum).OutDryBulbTemp; + Real64 WindSpeedExt = state.dataHeatBal->Zone(zoneNum).WindSpeed; + Real64 WindDirExt = state.dataHeatBal->Zone(zoneNum).WindDir; + Real64 thisMCPV = 0.0; + Real64 thisVAMFL = 0.0; + Real64 thisMCPTV = 0.0; + // Use air node information linked to the zone if defined - int NZ = state.dataHeatBal->Ventilation(j).ZonePtr; - state.dataHeatBal->Ventilation(j).FanPower = 0.0; - Real64 TempExt = state.dataHeatBal->Zone(NZ).OutDryBulbTemp; - Real64 WindSpeedExt = state.dataHeatBal->Zone(NZ).WindSpeed; - Real64 WindDirExt = state.dataHeatBal->Zone(NZ).WindDir; - if (state.dataHeatBal->Zone(NZ).HasLinkedOutAirNode) { - HumRatExt = state.dataLoopNodes->Node(state.dataHeatBal->Zone(NZ).LinkedOutAirNode).HumRat; - EnthalpyExt = state.dataLoopNodes->Node(state.dataHeatBal->Zone(NZ).LinkedOutAirNode).Enthalpy; + Real64 HumRatExt = 0.0; + Real64 EnthalpyExt = 0.0; + if (state.dataHeatBal->Zone(zoneNum).LinkedOutAirNode > 0) { + HumRatExt = state.dataLoopNodes->Node(state.dataHeatBal->Zone(zoneNum).LinkedOutAirNode).HumRat; + EnthalpyExt = state.dataLoopNodes->Node(state.dataHeatBal->Zone(zoneNum).LinkedOutAirNode).Enthalpy; } else { HumRatExt = state.dataEnvrn->OutHumRat; EnthalpyExt = state.dataEnvrn->OutEnthalpy; } - AirDensity = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, TempExt, HumRatExt); - CpAir = PsyCpAirFnW(HumRatExt); + Real64 AirDensity = + PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, TempExt, HumRatExt, RoutineNameVentilation); // Density of air (kg/m^3) + Real64 CpAir = PsyCpAirFnW(HumRatExt); + // Hybrid ventilation global control - if (state.dataHeatBal->Ventilation(j).HybridControlType == DataHeatBalance::HybridCtrlType::Global && - state.dataHeatBal->Ventilation(j).HybridControlMasterNum > 0) { - I = state.dataHeatBal->Ventilation(j).HybridControlMasterNum; - NH = state.dataHeatBal->Ventilation(I).ZonePtr; + int I = 0; + if (thisVentilation.HybridControlType == DataHeatBalance::HybridCtrlType::Global && thisVentilation.HybridControlMasterNum > 0) { + I = thisVentilation.HybridControlMasterNum; if (j == I) { - state.dataHeatBal->Ventilation(j).HybridControlMasterStatus = false; + thisVentilation.HybridControlMasterStatus = false; } } else { I = j; - NH = NZ; } + auto &hybridControlVentilation = state.dataHeatBal->Ventilation(I); + // Hybrid controlled zone MAT + Real64 hybridControlZoneMAT = state.dataZoneTempPredictorCorrector->zoneHeatBalance(hybridControlVentilation.ZonePtr).MixingMAT; + // Check scheduled temperatures - if (state.dataHeatBal->Ventilation(I).MinIndoorTempSchedPtr > 0) { - state.dataHeatBal->Ventilation(I).MinIndoorTemperature = - GetCurrentScheduleValue(state, state.dataHeatBal->Ventilation(I).MinIndoorTempSchedPtr); + if (hybridControlVentilation.MinIndoorTempSchedPtr > 0) { + hybridControlVentilation.MinIndoorTemperature = + ScheduleManager::GetCurrentScheduleValue(state, hybridControlVentilation.MinIndoorTempSchedPtr); } - if (state.dataHeatBal->Ventilation(I).MaxIndoorTempSchedPtr > 0) { - state.dataHeatBal->Ventilation(I).MaxIndoorTemperature = - GetCurrentScheduleValue(state, state.dataHeatBal->Ventilation(I).MaxIndoorTempSchedPtr); + if (hybridControlVentilation.MaxIndoorTempSchedPtr > 0) { + hybridControlVentilation.MaxIndoorTemperature = + ScheduleManager::GetCurrentScheduleValue(state, hybridControlVentilation.MaxIndoorTempSchedPtr); } // Ensure the minimum indoor temperature <= the maximum indoor temperature - if (state.dataHeatBal->Ventilation(I).MinIndoorTempSchedPtr > 0 || state.dataHeatBal->Ventilation(I).MaxIndoorTempSchedPtr > 0) { - if (state.dataHeatBal->Ventilation(I).MinIndoorTemperature > state.dataHeatBal->Ventilation(I).MaxIndoorTemperature) { - ++state.dataHeatBal->Ventilation(I).IndoorTempErrCount; - if (state.dataHeatBal->Ventilation(I).IndoorTempErrCount < 2) { + if (hybridControlVentilation.MinIndoorTempSchedPtr > 0 || hybridControlVentilation.MaxIndoorTempSchedPtr > 0) { + if (hybridControlVentilation.MinIndoorTemperature > hybridControlVentilation.MaxIndoorTemperature) { + ++hybridControlVentilation.IndoorTempErrCount; + if (hybridControlVentilation.IndoorTempErrCount < 2) { ShowWarningError( state, "Ventilation indoor temperature control: The minimum indoor temperature is above the maximum indoor temperature in " + - state.dataHeatBal->Ventilation(I).Name); + hybridControlVentilation.Name); ShowContinueError(state, "The minimum indoor temperature is set to the maximum indoor temperature. Simulation continues."); ShowContinueErrorTimeStamp(state, " Occurrence info:"); } else { ShowRecurringWarningErrorAtEnd(state, "The minimum indoor temperature is still above the maximum indoor temperature", - state.dataHeatBal->Ventilation(I).IndoorTempErrIndex, - state.dataHeatBal->Ventilation(I).MinIndoorTemperature, - state.dataHeatBal->Ventilation(I).MinIndoorTemperature); + hybridControlVentilation.IndoorTempErrIndex, + hybridControlVentilation.MinIndoorTemperature, + hybridControlVentilation.MinIndoorTemperature); } - state.dataHeatBal->Ventilation(I).MinIndoorTemperature = state.dataHeatBal->Ventilation(I).MaxIndoorTemperature; + hybridControlVentilation.MinIndoorTemperature = hybridControlVentilation.MaxIndoorTemperature; } } - if (state.dataHeatBal->Ventilation(I).MinOutdoorTempSchedPtr > 0) { - state.dataHeatBal->Ventilation(I).MinOutdoorTemperature = - GetCurrentScheduleValue(state, state.dataHeatBal->Ventilation(I).MinOutdoorTempSchedPtr); + if (hybridControlVentilation.MinOutdoorTempSchedPtr > 0) { + hybridControlVentilation.MinOutdoorTemperature = + ScheduleManager::GetCurrentScheduleValue(state, hybridControlVentilation.MinOutdoorTempSchedPtr); } - if (state.dataHeatBal->Ventilation(I).MaxOutdoorTempSchedPtr > 0) { - state.dataHeatBal->Ventilation(I).MaxOutdoorTemperature = - GetCurrentScheduleValue(state, state.dataHeatBal->Ventilation(I).MaxOutdoorTempSchedPtr); + if (hybridControlVentilation.MaxOutdoorTempSchedPtr > 0) { + hybridControlVentilation.MaxOutdoorTemperature = + ScheduleManager::GetCurrentScheduleValue(state, hybridControlVentilation.MaxOutdoorTempSchedPtr); } // Ensure the minimum outdoor temperature <= the maximum outdoor temperature - if (state.dataHeatBal->Ventilation(I).MinOutdoorTempSchedPtr > 0 || state.dataHeatBal->Ventilation(I).MaxOutdoorTempSchedPtr > 0) { - if (state.dataHeatBal->Ventilation(I).MinOutdoorTemperature > state.dataHeatBal->Ventilation(I).MaxOutdoorTemperature) { - ++state.dataHeatBal->Ventilation(I).OutdoorTempErrCount; - if (state.dataHeatBal->Ventilation(I).OutdoorTempErrCount < 2) { - ShowWarningError( - state, - "Ventilation outdoor temperature control: The minimum outdoor temperature is above the maximum outdoor temperature in " + - state.dataHeatBal->Ventilation(I).Name); + if (hybridControlVentilation.MinOutdoorTempSchedPtr > 0 || hybridControlVentilation.MaxOutdoorTempSchedPtr > 0) { + if (hybridControlVentilation.MinOutdoorTemperature > hybridControlVentilation.MaxOutdoorTemperature) { + ++hybridControlVentilation.OutdoorTempErrCount; + if (hybridControlVentilation.OutdoorTempErrCount < 2) { + ShowWarningError(state, + "Ventilation outdoor temperature control: The minimum outdoor temperature is above the maximum outdoor " + "temperature in " + + hybridControlVentilation.Name); ShowContinueError(state, "The minimum outdoor temperature is set to the maximum outdoor temperature. Simulation continues."); ShowContinueErrorTimeStamp(state, " Occurrence info:"); } else { ShowRecurringWarningErrorAtEnd(state, "The minimum outdoor temperature is still above the maximum outdoor temperature", - state.dataHeatBal->Ventilation(I).OutdoorTempErrIndex, - state.dataHeatBal->Ventilation(I).MinOutdoorTemperature, - state.dataHeatBal->Ventilation(I).MinOutdoorTemperature); + hybridControlVentilation.OutdoorTempErrIndex, + hybridControlVentilation.MinOutdoorTemperature, + hybridControlVentilation.MinOutdoorTemperature); } - state.dataHeatBal->Ventilation(I).MinIndoorTemperature = state.dataHeatBal->Ventilation(I).MaxIndoorTemperature; + hybridControlVentilation.MinIndoorTemperature = hybridControlVentilation.MaxIndoorTemperature; } } - if (state.dataHeatBal->Ventilation(I).DeltaTempSchedPtr > 0) { - state.dataHeatBal->Ventilation(I).DelTemperature = GetCurrentScheduleValue(state, state.dataHeatBal->Ventilation(I).DeltaTempSchedPtr); + if (hybridControlVentilation.DeltaTempSchedPtr > 0) { + hybridControlVentilation.DelTemperature = ScheduleManager::GetCurrentScheduleValue(state, hybridControlVentilation.DeltaTempSchedPtr); } // Skip this if the zone is below the minimum indoor temperature limit - if ((state.dataZoneEquip->ZMAT(NH) < state.dataHeatBal->Ventilation(I).MinIndoorTemperature) && - (!state.dataHeatBal->Ventilation(j).EMSSimpleVentOn)) - continue; + if ((hybridControlZoneMAT < hybridControlVentilation.MinIndoorTemperature) && (!thisVentilation.EMSSimpleVentOn)) continue; // Skip this if the zone is above the maximum indoor temperature limit - if ((state.dataZoneEquip->ZMAT(NH) > state.dataHeatBal->Ventilation(I).MaxIndoorTemperature) && - (!state.dataHeatBal->Ventilation(j).EMSSimpleVentOn)) - continue; + if ((hybridControlZoneMAT > hybridControlVentilation.MaxIndoorTemperature) && (!thisVentilation.EMSSimpleVentOn)) continue; // Skip if below the temperature difference limit (3/12/03 Negative DelTemperature allowed now) - if (((state.dataZoneEquip->ZMAT(NH) - TempExt) < state.dataHeatBal->Ventilation(I).DelTemperature) && - (!state.dataHeatBal->Ventilation(j).EMSSimpleVentOn)) - continue; + if (((hybridControlZoneMAT - TempExt) < hybridControlVentilation.DelTemperature) && (!thisVentilation.EMSSimpleVentOn)) continue; // Skip this if the outdoor temperature is below the minimum outdoor temperature limit - if ((TempExt < state.dataHeatBal->Ventilation(I).MinOutdoorTemperature) && (!state.dataHeatBal->Ventilation(j).EMSSimpleVentOn)) continue; + if ((TempExt < hybridControlVentilation.MinOutdoorTemperature) && (!thisVentilation.EMSSimpleVentOn)) continue; // Skip this if the outdoor temperature is above the maximum outdoor temperature limit - if ((TempExt > state.dataHeatBal->Ventilation(I).MaxOutdoorTemperature) && (!state.dataHeatBal->Ventilation(j).EMSSimpleVentOn)) continue; + if ((TempExt > hybridControlVentilation.MaxOutdoorTemperature) && (!thisVentilation.EMSSimpleVentOn)) continue; // Skip this if the outdoor wind speed is above the maximum windspeed limit - if ((WindSpeedExt > state.dataHeatBal->Ventilation(I).MaxWindSpeed) && (!state.dataHeatBal->Ventilation(j).EMSSimpleVentOn)) continue; + if ((WindSpeedExt > hybridControlVentilation.MaxWindSpeed) && (!thisVentilation.EMSSimpleVentOn)) continue; // Hybrid ventilation controls - if ((state.dataHeatBal->Ventilation(j).HybridControlType == DataHeatBalance::HybridCtrlType::Close) && - (!state.dataHeatBal->Ventilation(j).EMSSimpleVentOn)) - continue; - if (state.dataHeatBal->Ventilation(j).HybridControlType == DataHeatBalance::HybridCtrlType::Global && - state.dataHeatBal->Ventilation(j).HybridControlMasterNum > 0) { - if (j == I) state.dataHeatBal->Ventilation(j).HybridControlMasterStatus = true; + if ((thisVentilation.HybridControlType == DataHeatBalance::HybridCtrlType::Close) && (!thisVentilation.EMSSimpleVentOn)) continue; + if (thisVentilation.HybridControlType == DataHeatBalance::HybridCtrlType::Global && thisVentilation.HybridControlMasterNum > 0) { + if (j == I) thisVentilation.HybridControlMasterStatus = true; } - if (state.dataHeatBal->Ventilation(j).ModelType == DataHeatBalance::VentilationModelType::DesignFlowRate) { + if (thisVentilation.ModelType == DataHeatBalance::VentilationModelType::DesignFlowRate) { // CR6845 if calculated < 0, don't propagate. - VVF = state.dataHeatBal->Ventilation(j).DesignLevel * GetCurrentScheduleValue(state, state.dataHeatBal->Ventilation(j).SchedPtr); + VVF = thisVentilation.DesignLevel * ScheduleManager::GetCurrentScheduleValue(state, thisVentilation.SchedPtr); - if (state.dataHeatBal->Ventilation(j).EMSSimpleVentOn) VVF = state.dataHeatBal->Ventilation(j).EMSimpleVentFlowRate; + if (thisVentilation.EMSSimpleVentOn) VVF = thisVentilation.EMSimpleVentFlowRate; if (VVF < 0.0) VVF = 0.0; - state.dataZoneEquip->VentMCP(j) = - VVF * AirDensity * CpAir * - (state.dataHeatBal->Ventilation(j).ConstantTermCoef + - std::abs(TempExt - state.dataZoneEquip->ZMAT(NZ)) * state.dataHeatBal->Ventilation(j).TemperatureTermCoef + - WindSpeedExt * - (state.dataHeatBal->Ventilation(j).VelocityTermCoef + WindSpeedExt * state.dataHeatBal->Ventilation(j).VelocitySQTermCoef)); - if (state.dataZoneEquip->VentMCP(j) < 0.0) state.dataZoneEquip->VentMCP(j) = 0.0; - VAMFL_temp = state.dataZoneEquip->VentMCP(j) / CpAir; - if (state.dataHeatBal->Zone(NZ).zoneOAQuadratureSum) { - auto &thisZoneAirBalance = state.dataHeatBal->ZoneAirBalance(state.dataHeatBal->Zone(NZ).zoneOABalanceIndex); - switch (state.dataHeatBal->Ventilation(j).FanType) { + thisVentilation.MCP = VVF * AirDensity * CpAir * + (thisVentilation.ConstantTermCoef + std::abs(TempExt - thisMixingMAT) * thisVentilation.TemperatureTermCoef + + WindSpeedExt * (thisVentilation.VelocityTermCoef + WindSpeedExt * thisVentilation.VelocitySQTermCoef)); + if (thisVentilation.MCP < 0.0) thisVentilation.MCP = 0.0; + Real64 VAMFL_temp = thisVentilation.MCP / CpAir; + if (state.dataHeatBal->Zone(zoneNum).zoneOAQuadratureSum) { + auto &thisZoneAirBalance = state.dataHeatBal->ZoneAirBalance(state.dataHeatBal->Zone(zoneNum).zoneOABalanceIndex); + switch (thisVentilation.FanType) { // ventilation type based calculation case DataHeatBalance::VentilationType::Exhaust: { - thisZoneAirBalance.ExhMassFlowRate += state.dataZoneEquip->VentMCP(j) / CpAir; + thisZoneAirBalance.ExhMassFlowRate += VAMFL_temp; } break; case DataHeatBalance::VentilationType::Intake: { - thisZoneAirBalance.IntMassFlowRate += state.dataZoneEquip->VentMCP(j) / CpAir; + thisZoneAirBalance.IntMassFlowRate += VAMFL_temp; } break; case DataHeatBalance::VentilationType::Natural: { - thisZoneAirBalance.NatMassFlowRate += state.dataZoneEquip->VentMCP(j) / CpAir; + thisZoneAirBalance.NatMassFlowRate += VAMFL_temp; } break; case DataHeatBalance::VentilationType::Balanced: { - thisZoneAirBalance.BalMassFlowRate += state.dataZoneEquip->VentMCP(j) / CpAir; + thisZoneAirBalance.BalMassFlowRate += VAMFL_temp; } break; default: break; } } else { - state.dataHeatBalFanSys->MCPV(NZ) += state.dataZoneEquip->VentMCP(j); - state.dataHeatBalFanSys->VAMFL(NZ) += VAMFL_temp; - } - if (state.dataHeatBal->Ventilation(j).FanEfficiency > 0.0) { - state.dataHeatBal->Ventilation(j).FanPower = - VAMFL_temp * state.dataHeatBal->Ventilation(j).FanPressure / (state.dataHeatBal->Ventilation(j).FanEfficiency * AirDensity); - if (state.dataHeatBal->Ventilation(j).FanType == DataHeatBalance::VentilationType::Balanced) - state.dataHeatBal->Ventilation(j).FanPower *= 2.0; + thisMCPV = thisVentilation.MCP; + thisVAMFL = VAMFL_temp; + } + if (thisVentilation.FanEfficiency > 0.0) { + thisVentilation.FanPower = VAMFL_temp * thisVentilation.FanPressure / (thisVentilation.FanEfficiency * AirDensity); + if (thisVentilation.FanType == DataHeatBalance::VentilationType::Balanced) thisVentilation.FanPower *= 2.0; // calc electric if (state.afn->simulation_control.type == AirflowNetwork::ControlType::MultizoneWithDistributionOnlyDuringFanOperation) { - // CR7608 IF (.not. TurnFansOn .or. .not. AirflowNetworkZoneFlag(NZ)) & + // CR7608 IF (.not. TurnFansOn .or. .not. AirflowNetworkZoneFlag(zoneNum)) & if (!state.dataGlobal->KickOffSimulation) { - if (!(state.dataZoneEquip->ZoneEquipAvail(NZ) == CycleOn || state.dataZoneEquip->ZoneEquipAvail(NZ) == CycleOnZoneFansOnly) || - !state.afn->AirflowNetworkZoneFlag(NZ)) - state.dataHeatBal->ZnAirRpt(NZ).VentilFanElec += - state.dataHeatBal->Ventilation(j).FanPower * TimeStepSys * DataGlobalConstants::SecInHour; - } else if (!state.afn->AirflowNetworkZoneFlag(NZ)) { - state.dataHeatBal->ZnAirRpt(NZ).VentilFanElec += - state.dataHeatBal->Ventilation(j).FanPower * TimeStepSys * DataGlobalConstants::SecInHour; + if (!(state.dataZoneEquip->ZoneEquipAvail(zoneNum) == DataHVACGlobals::CycleOn || + state.dataZoneEquip->ZoneEquipAvail(zoneNum) == DataHVACGlobals::CycleOnZoneFansOnly) || + !state.afn->AirflowNetworkZoneFlag(zoneNum)) + state.dataHeatBal->ZnAirRpt(zoneNum).VentilFanElec += + thisVentilation.FanPower * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour; + } else if (!state.afn->AirflowNetworkZoneFlag(zoneNum)) { + state.dataHeatBal->ZnAirRpt(zoneNum).VentilFanElec += + thisVentilation.FanPower * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour; } } else { - state.dataHeatBal->ZnAirRpt(NZ).VentilFanElec += - state.dataHeatBal->Ventilation(j).FanPower * TimeStepSys * DataGlobalConstants::SecInHour; + state.dataHeatBal->ZnAirRpt(zoneNum).VentilFanElec += + thisVentilation.FanPower * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour; } } // Intake fans will add some heat to the air, raising the temperature for an intake fan... - if (state.dataHeatBal->Ventilation(j).FanType == DataHeatBalance::VentilationType::Intake || - state.dataHeatBal->Ventilation(j).FanType == DataHeatBalance::VentilationType::Balanced) { + if (thisVentilation.FanType == DataHeatBalance::VentilationType::Intake || + thisVentilation.FanType == DataHeatBalance::VentilationType::Balanced) { + Real64 OutletAirEnthalpy = 0.0; if (VAMFL_temp == 0.0) { OutletAirEnthalpy = EnthalpyExt; } else { - if (state.dataHeatBal->Ventilation(j).FanPower > 0.0) { - if (state.dataHeatBal->Ventilation(j).FanType == DataHeatBalance::VentilationType::Balanced) { - OutletAirEnthalpy = - EnthalpyExt + state.dataHeatBal->Ventilation(j).FanPower / VAMFL_temp / 2.0; // Half fan power to calculate inlet T + if (thisVentilation.FanPower > 0.0) { + if (thisVentilation.FanType == DataHeatBalance::VentilationType::Balanced) { + OutletAirEnthalpy = EnthalpyExt + thisVentilation.FanPower / VAMFL_temp / 2.0; // Half fan power to calculate inlet T } else { - OutletAirEnthalpy = EnthalpyExt + state.dataHeatBal->Ventilation(j).FanPower / VAMFL_temp; + OutletAirEnthalpy = EnthalpyExt + thisVentilation.FanPower / VAMFL_temp; } } else { OutletAirEnthalpy = EnthalpyExt; } } - state.dataHeatBal->Ventilation(j).AirTemp = PsyTdbFnHW(OutletAirEnthalpy, HumRatExt); + thisVentilation.AirTemp = Psychrometrics::PsyTdbFnHW(OutletAirEnthalpy, HumRatExt); } else { - state.dataHeatBal->Ventilation(j).AirTemp = TempExt; - } - if (!state.dataHeatBal->Zone(NZ).zoneOAQuadratureSum) - state.dataHeatBalFanSys->MCPTV(NZ) += state.dataZoneEquip->VentMCP(j) * state.dataHeatBal->Ventilation(j).AirTemp; - } - - if (state.dataHeatBal->Ventilation(j).ModelType == DataHeatBalance::VentilationModelType::WindAndStack) { - if (state.dataHeatBal->Ventilation(j).OpenEff != DataGlobalConstants::AutoCalculate) { - Cw = state.dataHeatBal->Ventilation(j).OpenEff; + thisVentilation.AirTemp = TempExt; + } + if (!state.dataHeatBal->Zone(zoneNum).zoneOAQuadratureSum) thisMCPTV = thisVentilation.MCP * thisVentilation.AirTemp; + } else if (thisVentilation.ModelType == DataHeatBalance::VentilationModelType::WindAndStack) { + Real64 Cw = 0.0; // Opening effectivenss + Real64 Cd = 0.0; // Discharge coefficent + Real64 angle = 0.0; // Angle between wind direction and effective angle + Real64 Qw = 0.0; // Volumetric flow driven by wind + Real64 Qst = 0.0; // Volumetric flow driven by stack effect + if (thisVentilation.OpenEff != DataGlobalConstants::AutoCalculate) { + Cw = thisVentilation.OpenEff; } else { // linear interpolation between effective angle and wind direction - angle = std::abs(WindDirExt - state.dataHeatBal->Ventilation(j).EffAngle); + angle = std::abs(WindDirExt - thisVentilation.EffAngle); if (angle > 180.0) angle -= 180.0; Cw = 0.55 + angle / 180.0 * (0.3 - 0.55); } - if (state.dataHeatBal->Ventilation(j).DiscCoef != DataGlobalConstants::AutoCalculate) { - Cd = state.dataHeatBal->Ventilation(j).DiscCoef; + if (thisVentilation.DiscCoef != DataGlobalConstants::AutoCalculate) { + Cd = thisVentilation.DiscCoef; } else { - Cd = 0.40 + 0.0045 * std::abs(TempExt - state.dataZoneEquip->ZMAT(NZ)); - } - Qw = Cw * state.dataHeatBal->Ventilation(j).OpenArea * - GetCurrentScheduleValue(state, state.dataHeatBal->Ventilation(j).OpenAreaSchedPtr) * WindSpeedExt; - Qst = Cd * state.dataHeatBal->Ventilation(j).OpenArea * - GetCurrentScheduleValue(state, state.dataHeatBal->Ventilation(j).OpenAreaSchedPtr) * - std::sqrt(2.0 * 9.81 * state.dataHeatBal->Ventilation(j).DH * std::abs(TempExt - state.dataZoneEquip->ZMAT(NZ)) / - (state.dataZoneEquip->ZMAT(NZ) + 273.15)); + Cd = 0.40 + 0.0045 * std::abs(TempExt - thisMixingMAT); + } + Qw = Cw * thisVentilation.OpenArea * ScheduleManager::GetCurrentScheduleValue(state, thisVentilation.OpenAreaSchedPtr) * WindSpeedExt; + Qst = Cd * thisVentilation.OpenArea * ScheduleManager::GetCurrentScheduleValue(state, thisVentilation.OpenAreaSchedPtr) * + std::sqrt(2.0 * 9.81 * thisVentilation.DH * std::abs(TempExt - thisMixingMAT) / (thisMixingMAT + 273.15)); VVF = std::sqrt(Qw * Qw + Qst * Qst); - if (state.dataHeatBal->Ventilation(j).EMSSimpleVentOn) VVF = state.dataHeatBal->Ventilation(j).EMSimpleVentFlowRate; + if (thisVentilation.EMSSimpleVentOn) VVF = thisVentilation.EMSimpleVentFlowRate; if (VVF < 0.0) VVF = 0.0; - state.dataZoneEquip->VentMCP(j) = VVF * AirDensity * CpAir; - if (state.dataZoneEquip->VentMCP(j) < 0.0) state.dataZoneEquip->VentMCP(j) = 0.0; - if (state.dataHeatBal->Zone(NZ).zoneOAQuadratureSum) { - state.dataHeatBal->ZoneAirBalance(state.dataHeatBal->Zone(NZ).zoneOABalanceIndex).NatMassFlowRate += - state.dataZoneEquip->VentMCP(j) / CpAir; + thisVentilation.MCP = VVF * AirDensity * CpAir; + if (thisVentilation.MCP < 0.0) thisVentilation.MCP = 0.0; + if (state.dataHeatBal->Zone(zoneNum).zoneOAQuadratureSum) { + state.dataHeatBal->ZoneAirBalance(state.dataHeatBal->Zone(zoneNum).zoneOABalanceIndex).NatMassFlowRate += thisVentilation.MCP / CpAir; } else { - state.dataHeatBalFanSys->MCPV(NZ) += state.dataZoneEquip->VentMCP(j); - VAMFL_temp = state.dataZoneEquip->VentMCP(j) / CpAir; - state.dataHeatBalFanSys->VAMFL(NZ) += VAMFL_temp; - state.dataHeatBal->Ventilation(j).AirTemp = TempExt; - state.dataHeatBalFanSys->MCPTV(NZ) += state.dataZoneEquip->VentMCP(j) * state.dataHeatBal->Ventilation(j).AirTemp; + thisMCPV = thisVentilation.MCP; + thisVAMFL = thisVentilation.MCP / CpAir; + thisVentilation.AirTemp = TempExt; + thisMCPTV = thisVentilation.MCP * thisVentilation.AirTemp; } } + // Accumulate for zone and space + thisZoneHB.MCPV += thisMCPV; + thisZoneHB.VAMFL += thisVAMFL; + thisZoneHB.MCPTV += thisMCPTV; + if (state.dataHeatBal->doSpaceHeatBalance) { + auto &thisSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisVentilation.spaceIndex); + thisSpaceHB.MCPV += thisMCPV; + thisSpaceHB.VAMFL += thisVAMFL; + thisSpaceHB.MCPTV += thisMCPTV; + } } // Process Mixing for (int j = 1; j <= state.dataHeatBal->TotMixing; ++j) { - n = state.dataHeatBal->Mixing(j).ZonePtr; - m = state.dataHeatBal->Mixing(j).FromZone; - TD = state.dataHeatBal->Mixing(j).DeltaTemperature; + auto &thisMixing = state.dataHeatBal->Mixing(j); + int thisZoneNum = thisMixing.ZonePtr; + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisZoneNum); + int fromZoneNum = thisMixing.FromZone; + Real64 TD = thisMixing.DeltaTemperature; // Delta Temp limit + thisMixing.ReportFlag = false; + // Get scheduled delta temperature - if (state.dataHeatBal->Mixing(j).DeltaTempSchedPtr > 0) { - TD = GetCurrentScheduleValue(state, state.dataHeatBal->Mixing(j).DeltaTempSchedPtr); + if (thisMixing.DeltaTempSchedPtr > 0) { + TD = ScheduleManager::GetCurrentScheduleValue(state, thisMixing.DeltaTempSchedPtr); + } + Real64 TZN = 0.0; // Temperature of this Zone/Space + Real64 TZM = 0.0; // Temperature of From Zone/Space + 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 &fromSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisMixing.fromSpaceIndex); + TZN = thisSpaceHB.MixingMAT; // Temperature of this Space + TZM = fromSpaceHB.MixingMAT; // Temperature of From Space + HumRatZN = thisSpaceHB.MixingHumRat; // HumRat of this Space + HumRatZM = fromSpaceHB.MixingHumRat; // HumRat of From Space + } else { + auto &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 + HumRatZM = fromZoneHB.MixingHumRat; // HumRat of From Zone } - TZN = state.dataZoneEquip->ZMAT(n); - TZM = state.dataZoneEquip->ZMAT(m); + Real64 thisMCPM = 0.0; + Real64 thisMCPTM = 0.0; + Real64 thisMixingMassFlow = 0.0; + Real64 thisMixingMassFlowXHumRat = 0.0; // Hybrid ventilation controls - if (state.dataHeatBal->Mixing(j).HybridControlType == DataHeatBalance::HybridCtrlType::Close) continue; + if (thisMixing.HybridControlType == DataHeatBalance::HybridCtrlType::Close) continue; // Check temperature limit - MixingLimitFlag = false; + bool MixingLimitFlag = false; // Hybrid ventilation global control - if (state.dataHeatBal->Mixing(j).HybridControlType == DataHeatBalance::HybridCtrlType::Global && - state.dataHeatBal->Mixing(j).HybridControlMasterNum > 0) { - I = state.dataHeatBal->Mixing(j).HybridControlMasterNum; + int I = 0; + if (thisMixing.HybridControlType == DataHeatBalance::HybridCtrlType::Global && thisMixing.HybridControlMasterNum > 0) { + I = thisMixing.HybridControlMasterNum; if (!state.dataHeatBal->Ventilation(I).HybridControlMasterStatus) continue; } else { // Ensure the minimum indoor temperature <= the maximum indoor temperature - if (state.dataHeatBal->Mixing(j).MinIndoorTempSchedPtr > 0) - MixingTmin = GetCurrentScheduleValue(state, state.dataHeatBal->Mixing(j).MinIndoorTempSchedPtr); - if (state.dataHeatBal->Mixing(j).MaxIndoorTempSchedPtr > 0) - MixingTmax = GetCurrentScheduleValue(state, state.dataHeatBal->Mixing(j).MaxIndoorTempSchedPtr); - if (state.dataHeatBal->Mixing(j).MinIndoorTempSchedPtr > 0 && state.dataHeatBal->Mixing(j).MaxIndoorTempSchedPtr > 0) { + Real64 MixingTmin = 0.0; + Real64 MixingTmax = 0.0; + if (thisMixing.MinIndoorTempSchedPtr > 0) MixingTmin = ScheduleManager::GetCurrentScheduleValue(state, thisMixing.MinIndoorTempSchedPtr); + if (thisMixing.MaxIndoorTempSchedPtr > 0) MixingTmax = ScheduleManager::GetCurrentScheduleValue(state, thisMixing.MaxIndoorTempSchedPtr); + if (thisMixing.MinIndoorTempSchedPtr > 0 && thisMixing.MaxIndoorTempSchedPtr > 0) { if (MixingTmin > MixingTmax) { - ++state.dataHeatBal->Mixing(j).IndoorTempErrCount; - if (state.dataHeatBal->Mixing(j).IndoorTempErrCount < 2) { + ++thisMixing.IndoorTempErrCount; + if (thisMixing.IndoorTempErrCount < 2) { ShowWarningError(state, "Mixing zone temperature control: The minimum zone temperature is above the maximum zone temperature in " + - state.dataHeatBal->Mixing(j).Name); + thisMixing.Name); ShowContinueError(state, "The minimum zone temperature is set to the maximum zone temperature. Simulation continues."); ShowContinueErrorTimeStamp(state, " Occurrence info:"); } else { ShowRecurringWarningErrorAtEnd(state, "The minimum zone temperature is still above the maximum zone temperature", - state.dataHeatBal->Mixing(j).IndoorTempErrIndex, + thisMixing.IndoorTempErrIndex, MixingTmin, MixingTmin); } MixingTmin = MixingTmax; } } - if (state.dataHeatBal->Mixing(j).MinIndoorTempSchedPtr > 0) { + if (thisMixing.MinIndoorTempSchedPtr > 0) { if (TZN < MixingTmin) MixingLimitFlag = true; } - if (state.dataHeatBal->Mixing(j).MaxIndoorTempSchedPtr > 0) { + if (thisMixing.MaxIndoorTempSchedPtr > 0) { if (TZN > MixingTmax) MixingLimitFlag = true; } // Ensure the minimum source temperature <= the maximum source temperature - if (state.dataHeatBal->Mixing(j).MinSourceTempSchedPtr > 0) - MixingTmin = GetCurrentScheduleValue(state, state.dataHeatBal->Mixing(j).MinSourceTempSchedPtr); - if (state.dataHeatBal->Mixing(j).MaxSourceTempSchedPtr > 0) - MixingTmax = GetCurrentScheduleValue(state, state.dataHeatBal->Mixing(j).MaxSourceTempSchedPtr); - if (state.dataHeatBal->Mixing(j).MinSourceTempSchedPtr > 0 && state.dataHeatBal->Mixing(j).MaxSourceTempSchedPtr > 0) { + if (thisMixing.MinSourceTempSchedPtr > 0) MixingTmin = ScheduleManager::GetCurrentScheduleValue(state, thisMixing.MinSourceTempSchedPtr); + if (thisMixing.MaxSourceTempSchedPtr > 0) MixingTmax = ScheduleManager::GetCurrentScheduleValue(state, thisMixing.MaxSourceTempSchedPtr); + if (thisMixing.MinSourceTempSchedPtr > 0 && thisMixing.MaxSourceTempSchedPtr > 0) { if (MixingTmin > MixingTmax) { - ++state.dataHeatBal->Mixing(j).SourceTempErrCount; - if (state.dataHeatBal->Mixing(j).SourceTempErrCount < 2) { + ++thisMixing.SourceTempErrCount; + if (thisMixing.SourceTempErrCount < 2) { ShowWarningError( state, "Mixing source temperature control: The minimum source temperature is above the maximum source temperature in " + - state.dataHeatBal->Mixing(j).Name); + thisMixing.Name); ShowContinueError(state, "The minimum source temperature is set to the maximum source temperature. Simulation continues."); ShowContinueErrorTimeStamp(state, " Occurrence info:"); } else { ShowRecurringWarningErrorAtEnd(state, "The minimum source temperature is still above the maximum source temperature", - state.dataHeatBal->Mixing(j).SourceTempErrIndex, + thisMixing.SourceTempErrIndex, MixingTmin, MixingTmin); } MixingTmin = MixingTmax; } } - if (state.dataHeatBal->Mixing(j).MinSourceTempSchedPtr > 0) { + if (thisMixing.MinSourceTempSchedPtr > 0) { if (TZM < MixingTmin) MixingLimitFlag = true; } - if (state.dataHeatBal->Mixing(j).MaxSourceTempSchedPtr > 0) { + if (thisMixing.MaxSourceTempSchedPtr > 0) { if (TZM > MixingTmax) MixingLimitFlag = true; } // Ensure the minimum outdoor temperature <= the maximum outdoor temperature - Real64 TempExt = state.dataHeatBal->Zone(n).OutDryBulbTemp; - if (state.dataHeatBal->Mixing(j).MinOutdoorTempSchedPtr > 0) - MixingTmin = GetCurrentScheduleValue(state, state.dataHeatBal->Mixing(j).MinOutdoorTempSchedPtr); - if (state.dataHeatBal->Mixing(j).MaxOutdoorTempSchedPtr > 0) - MixingTmax = GetCurrentScheduleValue(state, state.dataHeatBal->Mixing(j).MaxOutdoorTempSchedPtr); - if (state.dataHeatBal->Mixing(j).MinOutdoorTempSchedPtr > 0 && state.dataHeatBal->Mixing(j).MaxOutdoorTempSchedPtr > 0) { + Real64 TempExt = state.dataHeatBal->Zone(thisZoneNum).OutDryBulbTemp; + if (thisMixing.MinOutdoorTempSchedPtr > 0) + MixingTmin = ScheduleManager::GetCurrentScheduleValue(state, thisMixing.MinOutdoorTempSchedPtr); + if (thisMixing.MaxOutdoorTempSchedPtr > 0) + MixingTmax = ScheduleManager::GetCurrentScheduleValue(state, thisMixing.MaxOutdoorTempSchedPtr); + if (thisMixing.MinOutdoorTempSchedPtr > 0 && thisMixing.MaxOutdoorTempSchedPtr > 0) { if (MixingTmin > MixingTmax) { - ++state.dataHeatBal->Mixing(j).OutdoorTempErrCount; - if (state.dataHeatBal->Mixing(j).OutdoorTempErrCount < 2) { - ShowWarningError( - state, - "Mixing outdoor temperature control: The minimum outdoor temperature is above the maximum outdoor temperature in " + - state.dataHeatBal->Mixing(j).Name); + ++thisMixing.OutdoorTempErrCount; + if (thisMixing.OutdoorTempErrCount < 2) { + ShowWarningError(state, + "Mixing outdoor temperature control: The minimum outdoor temperature is above the maximum outdoor " + "temperature in " + + thisMixing.Name); ShowContinueError(state, "The minimum outdoor temperature is set to the maximum source temperature. Simulation continues."); ShowContinueErrorTimeStamp(state, " Occurrence info:"); } else { ShowRecurringWarningErrorAtEnd(state, "The minimum outdoor temperature is still above the maximum outdoor temperature", - state.dataHeatBal->Mixing(j).OutdoorTempErrIndex, + thisMixing.OutdoorTempErrIndex, MixingTmin, MixingTmin); } MixingTmin = MixingTmax; } } - if (state.dataHeatBal->Mixing(j).MinOutdoorTempSchedPtr > 0) { + if (thisMixing.MinOutdoorTempSchedPtr > 0) { if (TempExt < MixingTmin) MixingLimitFlag = true; } - if (state.dataHeatBal->Mixing(j).MaxOutdoorTempSchedPtr > 0) { + if (thisMixing.MaxOutdoorTempSchedPtr > 0) { if (TempExt > MixingTmax) MixingLimitFlag = true; } } - if (state.dataHeatBal->Mixing(j).HybridControlType != DataHeatBalance::HybridCtrlType::Global && MixingLimitFlag) continue; - if (state.dataHeatBal->Mixing(j).HybridControlType == DataHeatBalance::HybridCtrlType::Global) TD = 0.0; + if (thisMixing.HybridControlType != DataHeatBalance::HybridCtrlType::Global && MixingLimitFlag) continue; + if (thisMixing.HybridControlType == DataHeatBalance::HybridCtrlType::Global) TD = 0.0; + + // Per Jan 17, 2008 conference call, agreed to use average conditions for Rho, Cp and Hfg + Real64 AirDensity = PsyRhoAirFnPbTdbW( + state, state.dataEnvrn->OutBaroPress, (TZN + TZM) / 2.0, (HumRatZN + HumRatZM) / 2.0, RoutineNameMixing); // Density of air (kg/m^3) + Real64 CpAir = PsyCpAirFnW((HumRatZN + HumRatZM) / 2.0); // Use average conditions // If TD equals zero (default) set coefficients for full mixing otherwise test // for mixing conditions if user input delta temp > 0, then from zone temp (TZM) @@ -5628,203 +5714,210 @@ void CalcAirFlowSimple(EnergyPlusData &state, // then from zone temp (TZM) must be TD degrees cooler than zone temp (TZN). if (TD < 0.0) { if (TZM < TZN + TD) { - // Per Jan 17, 2008 conference call, agreed to use average conditions for Rho, Cp and Hfg - // RhoAirM = PsyRhoAirFnPbTdbW(state, OutBaroPress,tzm,ZHumRat(m)) - // MCP=Mixing(J)%DesiredAirFlowRate * PsyCpAirFnW(ZHumRat(m),tzm) * RhoAirM - AirDensity = PsyRhoAirFnPbTdbW(state, - state.dataEnvrn->OutBaroPress, - (TZN + TZM) / 2.0, - (state.dataZoneEquip->ZHumRat(n) + state.dataZoneEquip->ZHumRat(m)) / 2.0); - CpAir = PsyCpAirFnW((state.dataZoneEquip->ZHumRat(n) + state.dataZoneEquip->ZHumRat(m)) / 2.0); // Use average conditions - - state.dataHeatBal->Mixing(j).DesiredAirFlowRate = state.dataHeatBal->Mixing(j).DesiredAirFlowRateSaved; - if (state.dataHeatBalFanSys->ZoneMassBalanceFlag(n) && AdjustZoneMixingFlowFlag) { - if (state.dataHeatBal->Mixing(j).MixingMassFlowRate > 0.0) { - state.dataHeatBal->Mixing(j).DesiredAirFlowRate = state.dataHeatBal->Mixing(j).MixingMassFlowRate / AirDensity; + + thisMixing.DesiredAirFlowRate = thisMixing.DesiredAirFlowRateSaved; + if (state.dataHeatBalFanSys->ZoneMassBalanceFlag(thisZoneNum) && AdjustZoneMixingFlowFlag) { + if (thisMixing.MixingMassFlowRate > 0.0) { + thisMixing.DesiredAirFlowRate = thisMixing.MixingMassFlowRate / AirDensity; } } - state.dataHeatBal->Mixing(j).MixingMassFlowRate = state.dataHeatBal->Mixing(j).DesiredAirFlowRate * AirDensity; + thisMixing.MixingMassFlowRate = thisMixing.DesiredAirFlowRate * AirDensity; - MCP = state.dataHeatBal->Mixing(j).DesiredAirFlowRate * CpAir * AirDensity; - state.dataHeatBalFanSys->MCPM(n) += MCP; - state.dataHeatBalFanSys->MCPTM(n) += MCP * TZM; + thisMCPM = thisMixing.MixingMassFlowRate * CpAir; + thisMCPTM = thisMCPM * TZN; // Now to determine the moisture conditions - state.dataHeatBalFanSys->MixingMassFlowZone(n) += state.dataHeatBal->Mixing(j).DesiredAirFlowRate * AirDensity; - state.dataHeatBalFanSys->MixingMassFlowXHumRat(n) += - state.dataHeatBal->Mixing(j).DesiredAirFlowRate * AirDensity * state.dataZoneEquip->ZHumRat(m); + thisMixingMassFlow = thisMixing.DesiredAirFlowRate * AirDensity; + thisMixingMassFlowXHumRat = thisMixing.DesiredAirFlowRate * AirDensity * HumRatZM; if (state.dataContaminantBalance->Contaminant.CO2Simulation) { - state.dataContaminantBalance->MixingMassFlowCO2(n) += - state.dataHeatBal->Mixing(j).DesiredAirFlowRate * AirDensity * state.dataContaminantBalance->ZoneAirCO2(m); + state.dataContaminantBalance->MixingMassFlowCO2(thisZoneNum) += + thisMixing.DesiredAirFlowRate * AirDensity * state.dataContaminantBalance->ZoneAirCO2(fromZoneNum); } if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) { - state.dataContaminantBalance->MixingMassFlowGC(n) += - state.dataHeatBal->Mixing(j).DesiredAirFlowRate * AirDensity * state.dataContaminantBalance->ZoneAirGC(m); + state.dataContaminantBalance->MixingMassFlowGC(thisZoneNum) += + thisMixing.DesiredAirFlowRate * AirDensity * state.dataContaminantBalance->ZoneAirGC(fromZoneNum); } - state.dataZoneEquip->MixingReportFlag(j) = true; + thisMixing.ReportFlag = true; } - } - if (TD > 0.0) { + } else if (TD > 0.0) { if (TZM > TZN + TD) { - // RhoAirM = PsyRhoAirFnPbTdbW(state, OutBaroPress,tzm,ZHumRat(m)) - // MCP=Mixing(J)%DesiredAirFlowRate * PsyCpAirFnW(ZHumRat(m),tzm) * RhoAirM - AirDensity = PsyRhoAirFnPbTdbW(state, - state.dataEnvrn->OutBaroPress, - (TZN + TZM) / 2.0, - (state.dataZoneEquip->ZHumRat(n) + state.dataZoneEquip->ZHumRat(m)) / 2.0); // Use avg conditions - CpAir = PsyCpAirFnW((state.dataZoneEquip->ZHumRat(n) + state.dataZoneEquip->ZHumRat(m)) / 2.0); // Use average conditions - - state.dataHeatBal->Mixing(j).DesiredAirFlowRate = state.dataHeatBal->Mixing(j).DesiredAirFlowRateSaved; - if (state.dataHeatBalFanSys->ZoneMassBalanceFlag(n) && AdjustZoneMixingFlowFlag) { - if (state.dataHeatBal->Mixing(j).MixingMassFlowRate > 0.0) { - state.dataHeatBal->Mixing(j).DesiredAirFlowRate = state.dataHeatBal->Mixing(j).MixingMassFlowRate / AirDensity; + thisMixing.DesiredAirFlowRate = thisMixing.DesiredAirFlowRateSaved; + if (state.dataHeatBalFanSys->ZoneMassBalanceFlag(thisZoneNum) && AdjustZoneMixingFlowFlag) { + if (thisMixing.MixingMassFlowRate > 0.0) { + thisMixing.DesiredAirFlowRate = thisMixing.MixingMassFlowRate / AirDensity; } } - state.dataHeatBal->Mixing(j).MixingMassFlowRate = state.dataHeatBal->Mixing(j).DesiredAirFlowRate * AirDensity; + thisMixing.MixingMassFlowRate = thisMixing.DesiredAirFlowRate * AirDensity; - MCP = state.dataHeatBal->Mixing(j).DesiredAirFlowRate * CpAir * AirDensity; - state.dataHeatBalFanSys->MCPM(n) += MCP; - state.dataHeatBalFanSys->MCPTM(n) += MCP * TZM; + thisMCPM = thisMixing.MixingMassFlowRate * CpAir; + thisMCPTM = thisMCPM * TZM; // Now to determine the moisture conditions - state.dataHeatBalFanSys->MixingMassFlowZone(n) += state.dataHeatBal->Mixing(j).DesiredAirFlowRate * AirDensity; - state.dataHeatBalFanSys->MixingMassFlowXHumRat(n) += - state.dataHeatBal->Mixing(j).DesiredAirFlowRate * AirDensity * state.dataZoneEquip->ZHumRat(m); + thisMixingMassFlow = thisMixing.MixingMassFlowRate; + thisMixingMassFlowXHumRat = thisMixing.MixingMassFlowRate * HumRatZM; if (state.dataContaminantBalance->Contaminant.CO2Simulation) { - state.dataContaminantBalance->MixingMassFlowCO2(n) += - state.dataHeatBal->Mixing(j).DesiredAirFlowRate * AirDensity * state.dataContaminantBalance->ZoneAirCO2(m); + state.dataContaminantBalance->MixingMassFlowCO2(thisZoneNum) += + thisMixing.MixingMassFlowRate * state.dataContaminantBalance->ZoneAirCO2(fromZoneNum); } if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) { - state.dataContaminantBalance->MixingMassFlowGC(n) += - state.dataHeatBal->Mixing(j).DesiredAirFlowRate * AirDensity * state.dataContaminantBalance->ZoneAirGC(m); + state.dataContaminantBalance->MixingMassFlowGC(thisZoneNum) += + thisMixing.MixingMassFlowRate * state.dataContaminantBalance->ZoneAirGC(fromZoneNum); } - state.dataZoneEquip->MixingReportFlag(j) = true; + thisMixing.ReportFlag = true; } - } - if (TD == 0.0) { - // RhoAirM = PsyRhoAirFnPbTdbW(state, OutBaroPress,tzm,ZHumRat(m)) - // MCP=Mixing(J)%DesiredAirFlowRate * PsyCpAirFnW(ZHumRat(m),tzm) * RhoAirM - AirDensity = PsyRhoAirFnPbTdbW(state, - state.dataEnvrn->OutBaroPress, - (TZN + TZM) / 2.0, - (state.dataZoneEquip->ZHumRat(n) + state.dataZoneEquip->ZHumRat(m)) / 2.0, - RoutineNameMixing); // Use avg conditions - CpAir = PsyCpAirFnW((state.dataZoneEquip->ZHumRat(n) + state.dataZoneEquip->ZHumRat(m)) / 2.0); // Use average conditions - - state.dataHeatBal->Mixing(j).DesiredAirFlowRate = state.dataHeatBal->Mixing(j).DesiredAirFlowRateSaved; - if (state.dataHeatBalFanSys->ZoneMassBalanceFlag(n) && AdjustZoneMixingFlowFlag) { - if (state.dataHeatBal->Mixing(j).MixingMassFlowRate > 0.0) { - state.dataHeatBal->Mixing(j).DesiredAirFlowRate = state.dataHeatBal->Mixing(j).MixingMassFlowRate / AirDensity; - } - } - state.dataHeatBal->Mixing(j).MixingMassFlowRate = state.dataHeatBal->Mixing(j).DesiredAirFlowRate * AirDensity; - - MCP = state.dataHeatBal->Mixing(j).DesiredAirFlowRate * CpAir * AirDensity; - state.dataHeatBalFanSys->MCPM(n) += MCP; - state.dataHeatBalFanSys->MCPTM(n) += MCP * TZM; + } else if (TD == 0.0) { + thisMixing.DesiredAirFlowRate = thisMixing.DesiredAirFlowRateSaved; + if (state.dataHeatBalFanSys->ZoneMassBalanceFlag(thisZoneNum) && AdjustZoneMixingFlowFlag) { + if (thisMixing.MixingMassFlowRate > 0.0) { + thisMixing.DesiredAirFlowRate = thisMixing.MixingMassFlowRate / AirDensity; + } + } + thisMixing.MixingMassFlowRate = thisMixing.DesiredAirFlowRate * AirDensity; + + thisMCPM = thisMixing.MixingMassFlowRate * CpAir; + thisMCPTM = thisMCPM * TZM; // Now to determine the moisture conditions - state.dataHeatBalFanSys->MixingMassFlowZone(n) += state.dataHeatBal->Mixing(j).DesiredAirFlowRate * AirDensity; - state.dataHeatBalFanSys->MixingMassFlowXHumRat(n) += - state.dataHeatBal->Mixing(j).DesiredAirFlowRate * AirDensity * state.dataZoneEquip->ZHumRat(m); + thisMixingMassFlow = thisMixing.MixingMassFlowRate; + thisMixingMassFlowXHumRat = thisMixing.MixingMassFlowRate * HumRatZM; if (state.dataContaminantBalance->Contaminant.CO2Simulation) { - state.dataContaminantBalance->MixingMassFlowCO2(n) += - state.dataHeatBal->Mixing(j).DesiredAirFlowRate * AirDensity * state.dataContaminantBalance->ZoneAirCO2(m); + state.dataContaminantBalance->MixingMassFlowCO2(thisZoneNum) += + thisMixing.MixingMassFlowRate * state.dataContaminantBalance->ZoneAirCO2(fromZoneNum); } if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) { - state.dataContaminantBalance->MixingMassFlowGC(n) += - state.dataHeatBal->Mixing(j).DesiredAirFlowRate * AirDensity * state.dataContaminantBalance->ZoneAirGC(m); + state.dataContaminantBalance->MixingMassFlowGC(thisZoneNum) += + thisMixing.MixingMassFlowRate * state.dataContaminantBalance->ZoneAirGC(fromZoneNum); } - state.dataZoneEquip->MixingReportFlag(j) = true; + thisMixing.ReportFlag = true; + } + // Accumulate for zone and space + thisZoneHB.MCPM += thisMCPM; + thisZoneHB.MCPTM += thisMCPTM; + thisZoneHB.MixingMassFlowZone += thisMixingMassFlow; + thisZoneHB.MixingMassFlowXHumRat += thisMixingMassFlowXHumRat; + if (state.dataHeatBal->doSpaceHeatBalance) { + auto &thisSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisMixing.spaceIndex); + thisSpaceHB.MCPM += thisMCPM; + thisSpaceHB.MCPTM += thisMCPTM; + thisSpaceHB.MixingMassFlowZone += thisMixingMassFlow; + thisSpaceHB.MixingMassFlowXHumRat += thisMixingMassFlowXHumRat; } } // COMPUTE CROSS ZONE // AIR MIXING for (int j = 1; j <= state.dataHeatBal->TotCrossMixing; ++j) { - n = state.dataHeatBal->CrossMixing(j).ZonePtr; - m = state.dataHeatBal->CrossMixing(j).FromZone; - TD = state.dataHeatBal->CrossMixing(j).DeltaTemperature; + auto &thisCrossMixing = state.dataHeatBal->CrossMixing(j); + int thisZoneNum = thisCrossMixing.ZonePtr; + thisCrossMixing.ReportFlag = false; + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisZoneNum); + int fromZoneNum = thisCrossMixing.FromZone; + auto &fromZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(fromZoneNum); + Real64 TD = thisCrossMixing.DeltaTemperature; // Delta Temp limit // Get scheduled delta temperature - if (state.dataHeatBal->CrossMixing(j).DeltaTempSchedPtr > 0) { - TD = GetCurrentScheduleValue(state, state.dataHeatBal->CrossMixing(j).DeltaTempSchedPtr); + if (thisCrossMixing.DeltaTempSchedPtr > 0) { + TD = ScheduleManager::GetCurrentScheduleValue(state, thisCrossMixing.DeltaTempSchedPtr); } + Real64 thisMCPxM = 0.0; + Real64 thisMCPTxM = 0.0; + Real64 thisXMixingMassFlow = 0.0; + Real64 thisXMixingMassFlowXHumRat = 0.0; + Real64 fromMCPxM = 0.0; + Real64 fromMCPTxM = 0.0; + Real64 fromXMixingMassFlowXHumRat = 0.0; if (TD >= 0.0) { - TZN = state.dataZoneEquip->ZMAT(n); - TZM = state.dataZoneEquip->ZMAT(m); + Real64 TZN = 0.0; // Temperature of this Zone/Space + Real64 TZM = 0.0; // Temperature of From Zone/Space + 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 &fromSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisCrossMixing.fromSpaceIndex); + TZN = thisSpaceHB.MixingMAT; // Temperature of this Space + TZM = fromSpaceHB.MixingMAT; // Temperature of From Space + HumRatZN = thisSpaceHB.MixingHumRat; // HumRat of this Space + HumRatZM = fromSpaceHB.MixingHumRat; // HumRat of From Space + } else { + TZN = thisZoneHB.MixingMAT; // Temperature of this zone + TZM = fromZoneHB.MixingMAT; // Temperature of From Zone + HumRatZN = thisZoneHB.MixingHumRat; // HumRat of this zone + HumRatZM = fromZoneHB.MixingHumRat; // HumRat of From Zone + } // Check temperature limit - MixingLimitFlag = false; + bool MixingLimitFlag = false; // Ensure the minimum indoor temperature <= the maximum indoor temperature - if (state.dataHeatBal->CrossMixing(j).MinIndoorTempSchedPtr > 0) - MixingTmin = GetCurrentScheduleValue(state, state.dataHeatBal->CrossMixing(j).MinIndoorTempSchedPtr); - if (state.dataHeatBal->CrossMixing(j).MaxIndoorTempSchedPtr > 0) - MixingTmax = GetCurrentScheduleValue(state, state.dataHeatBal->CrossMixing(j).MaxIndoorTempSchedPtr); - if (state.dataHeatBal->CrossMixing(j).MinIndoorTempSchedPtr > 0 && state.dataHeatBal->CrossMixing(j).MaxIndoorTempSchedPtr > 0) { + Real64 MixingTmin = 0.0; + Real64 MixingTmax = 0.0; + if (thisCrossMixing.MinIndoorTempSchedPtr > 0) + MixingTmin = ScheduleManager::GetCurrentScheduleValue(state, thisCrossMixing.MinIndoorTempSchedPtr); + if (thisCrossMixing.MaxIndoorTempSchedPtr > 0) + MixingTmax = ScheduleManager::GetCurrentScheduleValue(state, thisCrossMixing.MaxIndoorTempSchedPtr); + if (thisCrossMixing.MinIndoorTempSchedPtr > 0 && thisCrossMixing.MaxIndoorTempSchedPtr > 0) { if (MixingTmin > MixingTmax) { - ++state.dataHeatBal->CrossMixing(j).IndoorTempErrCount; - if (state.dataHeatBal->CrossMixing(j).IndoorTempErrCount < 2) { + ++thisCrossMixing.IndoorTempErrCount; + if (thisCrossMixing.IndoorTempErrCount < 2) { ShowWarningError( state, "CrossMixing zone temperature control: The minimum zone temperature is above the maximum zone temperature in " + - state.dataHeatBal->CrossMixing(j).Name); + thisCrossMixing.Name); ShowContinueError(state, "The minimum zone temperature is set to the maximum zone temperature. Simulation continues."); ShowContinueErrorTimeStamp(state, " Occurrence info:"); } else { ShowRecurringWarningErrorAtEnd(state, "The minimum zone temperature is still above the maximum zone temperature", - state.dataHeatBal->CrossMixing(j).IndoorTempErrIndex, + thisCrossMixing.IndoorTempErrIndex, MixingTmin, MixingTmin); } MixingTmin = MixingTmax; } } - if (state.dataHeatBal->CrossMixing(j).MinIndoorTempSchedPtr > 0) { + if (thisCrossMixing.MinIndoorTempSchedPtr > 0) { if (TZN < MixingTmin) MixingLimitFlag = true; } - if (state.dataHeatBal->CrossMixing(j).MaxIndoorTempSchedPtr > 0) { + if (thisCrossMixing.MaxIndoorTempSchedPtr > 0) { if (TZN > MixingTmax) MixingLimitFlag = true; } // Ensure the minimum source temperature <= the maximum source temperature - if (state.dataHeatBal->CrossMixing(j).MinSourceTempSchedPtr > 0) - MixingTmin = GetCurrentScheduleValue(state, state.dataHeatBal->CrossMixing(j).MinSourceTempSchedPtr); - if (state.dataHeatBal->CrossMixing(j).MaxSourceTempSchedPtr > 0) - MixingTmax = GetCurrentScheduleValue(state, state.dataHeatBal->CrossMixing(j).MaxSourceTempSchedPtr); - if (state.dataHeatBal->CrossMixing(j).MinSourceTempSchedPtr > 0 && state.dataHeatBal->CrossMixing(j).MaxSourceTempSchedPtr > 0) { + if (thisCrossMixing.MinSourceTempSchedPtr > 0) + MixingTmin = ScheduleManager::GetCurrentScheduleValue(state, thisCrossMixing.MinSourceTempSchedPtr); + if (thisCrossMixing.MaxSourceTempSchedPtr > 0) + MixingTmax = ScheduleManager::GetCurrentScheduleValue(state, thisCrossMixing.MaxSourceTempSchedPtr); + if (thisCrossMixing.MinSourceTempSchedPtr > 0 && thisCrossMixing.MaxSourceTempSchedPtr > 0) { if (MixingTmin > MixingTmax) { - ++state.dataHeatBal->CrossMixing(j).SourceTempErrCount; - if (state.dataHeatBal->CrossMixing(j).SourceTempErrCount < 2) { - ShowWarningError( - state, - "CrossMixing source temperature control: The minimum source temperature is above the maximum source temperature in " + - state.dataHeatBal->CrossMixing(j).Name); + ++thisCrossMixing.SourceTempErrCount; + if (thisCrossMixing.SourceTempErrCount < 2) { + ShowWarningError(state, + "CrossMixing source temperature control: The minimum source temperature is above the maximum source " + "temperature in " + + thisCrossMixing.Name); ShowContinueError(state, "The minimum source temperature is set to the maximum source temperature. Simulation continues."); ShowContinueErrorTimeStamp(state, " Occurrence info:"); } else { ShowRecurringWarningErrorAtEnd(state, "The minimum source temperature is still above the maximum source temperature", - state.dataHeatBal->CrossMixing(j).SourceTempErrIndex, + thisCrossMixing.SourceTempErrIndex, MixingTmin, MixingTmin); } MixingTmin = MixingTmax; } } - if (state.dataHeatBal->CrossMixing(j).MinSourceTempSchedPtr > 0) { + if (thisCrossMixing.MinSourceTempSchedPtr > 0) { if (TZM < MixingTmin) MixingLimitFlag = true; } - if (state.dataHeatBal->CrossMixing(j).MaxSourceTempSchedPtr > 0) { + if (thisCrossMixing.MaxSourceTempSchedPtr > 0) { if (TZM > MixingTmax) MixingLimitFlag = true; } // Ensure the minimum outdoor temperature <= the maximum outdoor temperature - Real64 TempExt = state.dataHeatBal->Zone(n).OutDryBulbTemp; - if (state.dataHeatBal->CrossMixing(j).MinOutdoorTempSchedPtr > 0) - MixingTmin = GetCurrentScheduleValue(state, state.dataHeatBal->CrossMixing(j).MinOutdoorTempSchedPtr); - if (state.dataHeatBal->CrossMixing(j).MaxOutdoorTempSchedPtr > 0) - MixingTmax = GetCurrentScheduleValue(state, state.dataHeatBal->CrossMixing(j).MaxOutdoorTempSchedPtr); - if (state.dataHeatBal->CrossMixing(j).MinOutdoorTempSchedPtr > 0 && state.dataHeatBal->CrossMixing(j).MaxOutdoorTempSchedPtr > 0) { + Real64 TempExt = state.dataHeatBal->Zone(thisZoneNum).OutDryBulbTemp; + if (thisCrossMixing.MinOutdoorTempSchedPtr > 0) + MixingTmin = ScheduleManager::GetCurrentScheduleValue(state, thisCrossMixing.MinOutdoorTempSchedPtr); + if (thisCrossMixing.MaxOutdoorTempSchedPtr > 0) + MixingTmax = ScheduleManager::GetCurrentScheduleValue(state, thisCrossMixing.MaxOutdoorTempSchedPtr); + if (thisCrossMixing.MinOutdoorTempSchedPtr > 0 && thisCrossMixing.MaxOutdoorTempSchedPtr > 0) { if (MixingTmin > MixingTmax) { - ++state.dataHeatBal->CrossMixing(j).OutdoorTempErrCount; - if (state.dataHeatBal->CrossMixing(j).OutdoorTempErrCount < 2) { + ++thisCrossMixing.OutdoorTempErrCount; + if (thisCrossMixing.OutdoorTempErrCount < 2) { ShowWarningError(state, "CrossMixing outdoor temperature control: The minimum outdoor temperature is above the maximum outdoor " "temperature in " + @@ -5834,61 +5927,77 @@ void CalcAirFlowSimple(EnergyPlusData &state, } else { ShowRecurringWarningErrorAtEnd(state, "The minimum outdoor temperature is still above the maximum outdoor temperature", - state.dataHeatBal->CrossMixing(j).OutdoorTempErrIndex, + thisCrossMixing.OutdoorTempErrIndex, MixingTmin, MixingTmin); } MixingTmin = MixingTmax; } } - if (state.dataHeatBal->CrossMixing(j).MinOutdoorTempSchedPtr > 0) { + if (thisCrossMixing.MinOutdoorTempSchedPtr > 0) { if (TempExt < MixingTmin) MixingLimitFlag = true; } - if (state.dataHeatBal->CrossMixing(j).MaxOutdoorTempSchedPtr > 0) { + if (thisCrossMixing.MaxOutdoorTempSchedPtr > 0) { if (TempExt > MixingTmax) MixingLimitFlag = true; } if (MixingLimitFlag) continue; if ((TD == 0.0 || (TD > 0.0 && (TZM - TZN) >= TD))) { - state.dataZoneEquip->CrossMixingReportFlag(j) = true; // set reporting flag + thisCrossMixing.ReportFlag = true; } if ((TD <= 0.0) || ((TD > 0.0) && (TZM - TZN >= TD))) { // SET COEFFICIENTS . Real64 Tavg = (TZN + TZM) / 2.0; - Real64 Wavg = (state.dataZoneEquip->ZHumRat(n) + state.dataZoneEquip->ZHumRat(m)) / 2.0; - AirDensity = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, Tavg, Wavg, RoutineNameCrossMixing); - CpAir = PsyCpAirFnW(Wavg); - MCPxN = state.dataHeatBal->CrossMixing(j).DesiredAirFlowRate * CpAir * AirDensity; - state.dataHeatBalFanSys->MCPM(n) += MCPxN; + Real64 Wavg = (HumRatZN + HumRatZM) / 2.0; + Real64 AirDensity = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, Tavg, Wavg, RoutineNameCrossMixing); + Real64 CpAir = PsyCpAirFnW(Wavg); + thisXMixingMassFlow = thisCrossMixing.DesiredAirFlowRate * AirDensity; + thisMCPxM = thisXMixingMassFlow * CpAir; - MCPxM = state.dataHeatBal->CrossMixing(j).DesiredAirFlowRate * CpAir * AirDensity; - state.dataHeatBalFanSys->MCPM(m) += MCPxM; - state.dataHeatBalFanSys->MCPTM(n) += MCPxM * TZM; - state.dataHeatBalFanSys->MCPTM(m) += MCPxN * TZN; + fromMCPxM = thisMCPxM; + thisMCPTxM = thisMCPxM * TZM; + fromMCPTxM = fromMCPxM * TZN; // Now to determine the moisture conditions - state.dataHeatBalFanSys->MixingMassFlowZone(m) += state.dataHeatBal->CrossMixing(j).DesiredAirFlowRate * AirDensity; - state.dataHeatBalFanSys->MixingMassFlowXHumRat(m) += - state.dataHeatBal->CrossMixing(j).DesiredAirFlowRate * AirDensity * state.dataZoneEquip->ZHumRat(n); + fromXMixingMassFlowXHumRat = thisXMixingMassFlow * HumRatZN; + thisXMixingMassFlowXHumRat = thisXMixingMassFlow * HumRatZM; - state.dataHeatBalFanSys->MixingMassFlowZone(n) += state.dataHeatBal->CrossMixing(j).DesiredAirFlowRate * AirDensity; - state.dataHeatBalFanSys->MixingMassFlowXHumRat(n) += - state.dataHeatBal->CrossMixing(j).DesiredAirFlowRate * AirDensity * state.dataZoneEquip->ZHumRat(m); if (state.dataContaminantBalance->Contaminant.CO2Simulation) { - state.dataContaminantBalance->MixingMassFlowCO2(m) += - state.dataHeatBal->CrossMixing(j).DesiredAirFlowRate * AirDensity * state.dataContaminantBalance->ZoneAirCO2(n); - state.dataContaminantBalance->MixingMassFlowCO2(n) += - state.dataHeatBal->CrossMixing(j).DesiredAirFlowRate * AirDensity * state.dataContaminantBalance->ZoneAirCO2(m); + state.dataContaminantBalance->MixingMassFlowCO2(fromZoneNum) += + thisXMixingMassFlow * state.dataContaminantBalance->ZoneAirCO2(thisZoneNum); + state.dataContaminantBalance->MixingMassFlowCO2(thisZoneNum) += + thisXMixingMassFlow * state.dataContaminantBalance->ZoneAirCO2(fromZoneNum); } if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) { - state.dataContaminantBalance->MixingMassFlowGC(m) += - state.dataHeatBal->CrossMixing(j).DesiredAirFlowRate * AirDensity * state.dataContaminantBalance->ZoneAirGC(n); - state.dataContaminantBalance->MixingMassFlowGC(n) += - state.dataHeatBal->CrossMixing(j).DesiredAirFlowRate * AirDensity * state.dataContaminantBalance->ZoneAirGC(m); + state.dataContaminantBalance->MixingMassFlowGC(fromZoneNum) += + thisXMixingMassFlow * state.dataContaminantBalance->ZoneAirGC(thisZoneNum); + state.dataContaminantBalance->MixingMassFlowGC(thisZoneNum) += + thisXMixingMassFlow * state.dataContaminantBalance->ZoneAirGC(fromZoneNum); } } } + // Accumulate for zone and space + thisZoneHB.MCPM += thisMCPxM; + thisZoneHB.MCPTM += thisMCPTxM; + thisZoneHB.MixingMassFlowZone += thisXMixingMassFlow; + thisZoneHB.MixingMassFlowXHumRat += thisXMixingMassFlowXHumRat; + fromZoneHB.MCPM += fromMCPxM; + fromZoneHB.MCPTM += fromMCPTxM; + fromZoneHB.MixingMassFlowZone += thisXMixingMassFlow; + fromZoneHB.MixingMassFlowXHumRat += fromXMixingMassFlowXHumRat; + if (state.dataHeatBal->doSpaceHeatBalance) { + auto &thisSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisCrossMixing.spaceIndex); + auto &fromSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisCrossMixing.fromSpaceIndex); + thisSpaceHB.MCPM += thisMCPxM; + thisSpaceHB.MCPTM += thisMCPTxM; + thisSpaceHB.MixingMassFlowZone += thisXMixingMassFlow; + thisSpaceHB.MixingMassFlowXHumRat += thisXMixingMassFlowXHumRat; + fromSpaceHB.MCPM += fromMCPxM; + fromSpaceHB.MCPTM += fromMCPTxM; + fromSpaceHB.MixingMassFlowZone += thisXMixingMassFlow; + fromSpaceHB.MixingMassFlowXHumRat += fromXMixingMassFlowXHumRat; + } } // COMPUTE REFRIGERATION DOOR @@ -5897,26 +6006,31 @@ void CalcAirFlowSimple(EnergyPlusData &state, // Zone loops structured in getinput so only do each pair of zones bounding door once, even if multiple doors in one zone for (int ZoneA = 1; ZoneA <= (state.dataGlobal->NumOfZones - 1); ++ZoneA) { if (!state.dataHeatBal->RefDoorMixing(ZoneA).RefDoorMixFlag) continue; + auto &zoneAHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneA); + Real64 TZoneA = zoneAHB.MixingMAT; + Real64 HumRatZoneA = zoneAHB.MixingHumRat; + Real64 AirDensityZoneA = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, TZoneA, HumRatZoneA, RoutineNameRefrigerationDoorMixing); + Real64 CpAirZoneA = PsyCpAirFnW(HumRatZoneA); for (int j = 1; j <= state.dataHeatBal->RefDoorMixing(ZoneA).NumRefDoorConnections; ++j) { int ZoneB = state.dataHeatBal->RefDoorMixing(ZoneA).MateZonePtr(j); - Real64 TZoneA = state.dataZoneEquip->ZMAT(ZoneA); - Real64 TZoneB = state.dataZoneEquip->ZMAT(ZoneB); - Real64 HumRatZoneA = state.dataZoneEquip->ZHumRat(ZoneA); - Real64 HumRatZoneB = state.dataZoneEquip->ZHumRat(ZoneB); - Real64 AirDensityZoneA = - PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, TZoneA, HumRatZoneA, RoutineNameRefrigerationDoorMixing); - Real64 CpAirZoneA = PsyCpAirFnW(HumRatZoneA); - Real64 AirDensityZoneB = - PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, TZoneB, HumRatZoneB, RoutineNameRefrigerationDoorMixing); + auto &zoneBHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneB); + Real64 TZoneB = zoneBHB.MixingMAT; + Real64 HumRatZoneB = zoneBHB.MixingHumRat; Real64 CpAirZoneB = PsyCpAirFnW(HumRatZoneB); Real64 Tavg = (TZoneA + TZoneB) / 2.0; Real64 Wavg = (HumRatZoneA + HumRatZoneB) / 2.0; Real64 AirDensityAvg = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, Tavg, Wavg, RoutineNameRefrigerationDoorMixing); + // following variables used for refrigeration door mixing and all defined in EngRef + Real64 MassFlowDryAir = 0.0; + Real64 FDens = 0.0; + Real64 Fb = 0.0; if (state.dataHeatBal->RefDoorMixing(ZoneA).EMSRefDoorMixingOn(j)) { MassFlowDryAir = state.dataHeatBal->RefDoorMixing(ZoneA).VolRefDoorFlowRate(j) * AirDensityAvg; } else { - Real64 SchedDoorOpen = GetCurrentScheduleValue(state, state.dataHeatBal->RefDoorMixing(ZoneA).OpenSchedPtr(j)); + Real64 AirDensityZoneB = + PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, TZoneB, HumRatZoneB, RoutineNameRefrigerationDoorMixing); + Real64 SchedDoorOpen = ScheduleManager::GetCurrentScheduleValue(state, state.dataHeatBal->RefDoorMixing(ZoneA).OpenSchedPtr(j)); if (SchedDoorOpen == 0.0) continue; Real64 DoorHeight = state.dataHeatBal->RefDoorMixing(ZoneA).DoorHeight(j); Real64 DoorArea = state.dataHeatBal->RefDoorMixing(ZoneA).DoorArea(j); @@ -5951,16 +6065,34 @@ void CalcAirFlowSimple(EnergyPlusData &state, Real64 MassFlowXHumRatToA = MassFlowToA * HumRatZoneB; Real64 MassFlowXHumRatToB = MassFlowToB * HumRatZoneA; - state.dataHeatBalFanSys->MCPM(ZoneA) += MassFlowXCpToA; - state.dataHeatBalFanSys->MCPM(ZoneB) += MassFlowXCpToB; - state.dataHeatBalFanSys->MCPTM(ZoneA) += MassFlowXCpXTempToA; - state.dataHeatBalFanSys->MCPTM(ZoneB) += MassFlowXCpXTempToB; - - // Now to determine the moisture conditions - state.dataHeatBalFanSys->MixingMassFlowZone(ZoneA) += MassFlowToA; - state.dataHeatBalFanSys->MixingMassFlowZone(ZoneB) += MassFlowToB; - state.dataHeatBalFanSys->MixingMassFlowXHumRat(ZoneA) += MassFlowXHumRatToA; - state.dataHeatBalFanSys->MixingMassFlowXHumRat(ZoneB) += MassFlowXHumRatToB; + zoneAHB.MCPM += MassFlowXCpToA; + zoneBHB.MCPM += MassFlowXCpToB; + zoneAHB.MCPTM += MassFlowXCpXTempToA; + zoneBHB.MCPTM += MassFlowXCpXTempToB; + zoneAHB.MixingMassFlowZone += MassFlowToA; + zoneBHB.MixingMassFlowZone += MassFlowToB; + zoneAHB.MixingMassFlowXHumRat += MassFlowXHumRatToA; + zoneBHB.MixingMassFlowXHumRat += MassFlowXHumRatToB; + if (state.dataHeatBal->doSpaceHeatBalance) { + // ZoneRefrigerationDoorMixing has no space information, just zones + // Allocate mixing flows by space volume fraction of zone volume + for (int spaceNum : state.dataHeatBal->Zone(ZoneA).spaceIndexes) { + Real64 spaceFrac = state.dataHeatBal->space(spaceNum).fracZoneVolume; + auto &spaceAHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum); + spaceAHB.MCPM += MassFlowXCpToA * spaceFrac; + spaceAHB.MCPTM += MassFlowXCpXTempToA * spaceFrac; + spaceAHB.MixingMassFlowZone += MassFlowToA * spaceFrac; + spaceAHB.MixingMassFlowXHumRat += MassFlowXHumRatToA * spaceFrac; + } + for (int spaceNum : state.dataHeatBal->Zone(ZoneB).spaceIndexes) { + Real64 spaceFrac = state.dataHeatBal->space(spaceNum).fracZoneVolume; + auto &spaceBHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum); + spaceBHB.MCPM += MassFlowXCpToB * spaceFrac; + spaceBHB.MCPTM += MassFlowXCpXTempToB * spaceFrac; + spaceBHB.MixingMassFlowZone += MassFlowToB * spaceFrac; + spaceBHB.MixingMassFlowXHumRat += MassFlowXHumRatToB * spaceFrac; + } + } // Now to determine the CO2 and generic contaminant conditions if (state.dataContaminantBalance->Contaminant.CO2Simulation) { @@ -5979,112 +6111,96 @@ void CalcAirFlowSimple(EnergyPlusData &state, // Process the scheduled Infiltration for air heat balance depending on model type for (int j = 1; j <= state.dataHeatBal->TotInfiltration; ++j) { + auto &thisInfiltration = state.dataHeatBal->Infiltration(j); int NZ = state.dataHeatBal->Infiltration(j).ZonePtr; + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ); + Real64 tempInt = 0.0; + if (state.dataHeatBal->doSpaceHeatBalance) { + tempInt = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisInfiltration.spaceIndex).MixingMAT; + } else { + tempInt = thisZoneHB.MixingMAT; + } Real64 TempExt = state.dataHeatBal->Zone(NZ).OutDryBulbTemp; Real64 WindSpeedExt = state.dataHeatBal->Zone(NZ).WindSpeed; // Use air node information linked to the zone if defined - - if (state.dataHeatBal->Zone(NZ).HasLinkedOutAirNode) { + Real64 HumRatExt = 0.0; + if (state.dataHeatBal->Zone(NZ).LinkedOutAirNode > 0) { HumRatExt = state.dataLoopNodes->Node(state.dataHeatBal->Zone(NZ).LinkedOutAirNode).HumRat; } else { HumRatExt = state.dataEnvrn->OutHumRat; } - AirDensity = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, TempExt, HumRatExt, RoutineNameInfiltration); - CpAir = PsyCpAirFnW(HumRatExt); - - // CR7751 should maybe use code below, indoor conditions instead of outdoor conditions - // AirDensity = PsyRhoAirFnPbTdbW(state, OutBaroPress, ZMAT(NZ), ZHumRat(NZ)) - // CpAir = PsyCpAirFnW(ZHumRat(NZ),ZMAT(NZ)) - switch (state.dataHeatBal->Infiltration(j).ModelType) { - case DataHeatBalance::InfiltrationModelType::DesignFlowRate: { - IVF = state.dataHeatBal->Infiltration(j).DesignLevel * GetCurrentScheduleValue(state, state.dataHeatBal->Infiltration(j).SchedPtr); - // CR6845 if calculated < 0.0, don't propagate - if (IVF < 0.0) IVF = 0.0; - MCpI_temp = IVF * AirDensity * CpAir * - (state.dataHeatBal->Infiltration(j).ConstantTermCoef + - std::abs(TempExt - state.dataZoneEquip->ZMAT(NZ)) * state.dataHeatBal->Infiltration(j).TemperatureTermCoef + - WindSpeedExt * (state.dataHeatBal->Infiltration(j).VelocityTermCoef + - WindSpeedExt * state.dataHeatBal->Infiltration(j).VelocitySQTermCoef)); + Real64 AirDensity = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, TempExt, HumRatExt, RoutineNameInfiltration); + Real64 CpAir = PsyCpAirFnW(HumRatExt); + Real64 MCpI_temp = 0.0; + Real64 scheduleFrac = ScheduleManager::GetCurrentScheduleValue(state, thisInfiltration.SchedPtr); + if (scheduleFrac > 0.0) { + // CR7751 should maybe use code below, indoor conditions instead of outdoor conditions + // AirDensity = PsyRhoAirFnPbTdbW(state, OutBaroPress, MixingMAT(NZ), MixingHumRat(NZ)) + // CpAir = PsyCpAirFnW(MixingHumRat(NZ),MixingMAT(NZ)) + switch (thisInfiltration.ModelType) { + case DataHeatBalance::InfiltrationModelType::DesignFlowRate: { + IVF = thisInfiltration.DesignLevel * scheduleFrac; + // CR6845 if calculated < 0.0, don't propagate + if (IVF < 0.0) IVF = 0.0; + MCpI_temp = IVF * AirDensity * CpAir * + (thisInfiltration.ConstantTermCoef + std::abs(TempExt - tempInt) * thisInfiltration.TemperatureTermCoef + + WindSpeedExt * (thisInfiltration.VelocityTermCoef + WindSpeedExt * thisInfiltration.VelocitySQTermCoef)); + + if (MCpI_temp < 0.0) MCpI_temp = 0.0; + thisInfiltration.VolumeFlowRate = MCpI_temp / AirDensity / CpAir; + } break; + case DataHeatBalance::InfiltrationModelType::ShermanGrimsrud: { + // Sherman Grimsrud model as formulated in ASHRAE HoF + WindSpeedExt = state.dataEnvrn->WindSpeed; // formulated to use wind at Meterological Station rather than local + IVF = scheduleFrac * thisInfiltration.LeakageArea / 1000.0 * + std::sqrt(thisInfiltration.BasicStackCoefficient * std::abs(TempExt - tempInt) + + thisInfiltration.BasicWindCoefficient * pow_2(WindSpeedExt)); + if (IVF < 0.0) IVF = 0.0; + MCpI_temp = IVF * AirDensity * CpAir; + if (MCpI_temp < 0.0) MCpI_temp = 0.0; + thisInfiltration.VolumeFlowRate = MCpI_temp / AirDensity / CpAir; + } break; + case DataHeatBalance::InfiltrationModelType::AIM2: { + // Walker Wilson model as formulated in ASHRAE HoF + IVF = + scheduleFrac * std::sqrt(pow_2(thisInfiltration.FlowCoefficient * thisInfiltration.AIM2StackCoefficient * + std::pow(std::abs(TempExt - tempInt), thisInfiltration.PressureExponent)) + + pow_2(thisInfiltration.FlowCoefficient * thisInfiltration.AIM2WindCoefficient * + std::pow(thisInfiltration.ShelterFactor * WindSpeedExt, 2.0 * thisInfiltration.PressureExponent))); + if (IVF < 0.0) IVF = 0.0; + MCpI_temp = IVF * AirDensity * CpAir; + if (MCpI_temp < 0.0) MCpI_temp = 0.0; + thisInfiltration.VolumeFlowRate = MCpI_temp / AirDensity / CpAir; + } break; + default: + break; + } + } else { + thisInfiltration.VolumeFlowRate = 0.0; + MCpI_temp = 0.0; + } - if (MCpI_temp < 0.0) MCpI_temp = 0.0; - state.dataHeatBal->Infiltration(j).VolumeFlowRate = MCpI_temp / AirDensity / CpAir; - if (AdjustZoneInfiltrationFlowFlag && state.dataHeatBalFanSys->ZoneInfiltrationFlag(NZ)) { - if (state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment == DataHeatBalance::InfiltrationFlow::Adjust) { - // if ( Infiltration(j).MassFlowRate > 0.0 ) { - state.dataHeatBal->Infiltration(j).VolumeFlowRate = state.dataHeatBal->Infiltration(j).MassFlowRate / AirDensity; - MCpI_temp = state.dataHeatBal->Infiltration(j).VolumeFlowRate * AirDensity * CpAir; - //} - } - if (state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment == DataHeatBalance::InfiltrationFlow::Add) { - state.dataHeatBal->Infiltration(j).VolumeFlowRate = state.dataHeatBal->Infiltration(j).VolumeFlowRate + - state.dataHeatBal->MassConservation(NZ).InfiltrationMassFlowRate / AirDensity; - MCpI_temp = state.dataHeatBal->Infiltration(j).VolumeFlowRate * AirDensity * CpAir; - } - } - state.dataHeatBal->Infiltration(j).MassFlowRate = state.dataHeatBal->Infiltration(j).VolumeFlowRate * AirDensity; - } break; - case DataHeatBalance::InfiltrationModelType::ShermanGrimsrud: { - // Sherman Grimsrud model as formulated in ASHRAE HoF - WindSpeedExt = state.dataEnvrn->WindSpeed; // formulated to use wind at Meterological Station rather than local - IVF = GetCurrentScheduleValue(state, state.dataHeatBal->Infiltration(j).SchedPtr) * state.dataHeatBal->Infiltration(j).LeakageArea / - 1000.0 * - std::sqrt(state.dataHeatBal->Infiltration(j).BasicStackCoefficient * std::abs(TempExt - state.dataZoneEquip->ZMAT(NZ)) + - state.dataHeatBal->Infiltration(j).BasicWindCoefficient * pow_2(WindSpeedExt)); - if (IVF < 0.0) IVF = 0.0; - MCpI_temp = IVF * AirDensity * CpAir; - if (MCpI_temp < 0.0) MCpI_temp = 0.0; - state.dataHeatBal->Infiltration(j).VolumeFlowRate = MCpI_temp / AirDensity / CpAir; - if (AdjustZoneInfiltrationFlowFlag && state.dataHeatBalFanSys->ZoneInfiltrationFlag(NZ)) { - if (state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment == DataHeatBalance::InfiltrationFlow::Adjust) { - if (state.dataHeatBal->Infiltration(j).MassFlowRate > 0.0) { - state.dataHeatBal->Infiltration(j).VolumeFlowRate = state.dataHeatBal->Infiltration(j).MassFlowRate / AirDensity; - MCpI_temp = state.dataHeatBal->Infiltration(j).VolumeFlowRate * AirDensity * CpAir; - } - } - if (state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment == DataHeatBalance::InfiltrationFlow::Add) { - state.dataHeatBal->Infiltration(j).VolumeFlowRate = state.dataHeatBal->Infiltration(j).VolumeFlowRate + - state.dataHeatBal->MassConservation(NZ).InfiltrationMassFlowRate / AirDensity; - MCpI_temp = state.dataHeatBal->Infiltration(j).VolumeFlowRate * AirDensity * CpAir; - } - } - state.dataHeatBal->Infiltration(j).MassFlowRate = state.dataHeatBal->Infiltration(j).VolumeFlowRate * AirDensity; - } break; - case DataHeatBalance::InfiltrationModelType::AIM2: { - // Walker Wilson model as formulated in ASHRAE HoF - IVF = GetCurrentScheduleValue(state, state.dataHeatBal->Infiltration(j).SchedPtr) * - std::sqrt(pow_2(state.dataHeatBal->Infiltration(j).FlowCoefficient * state.dataHeatBal->Infiltration(j).AIM2StackCoefficient * - std::pow(std::abs(TempExt - state.dataZoneEquip->ZMAT(NZ)), state.dataHeatBal->Infiltration(j).PressureExponent)) + - pow_2(state.dataHeatBal->Infiltration(j).FlowCoefficient * state.dataHeatBal->Infiltration(j).AIM2WindCoefficient * - std::pow(state.dataHeatBal->Infiltration(j).ShelterFactor * WindSpeedExt, - 2.0 * state.dataHeatBal->Infiltration(j).PressureExponent))); - if (IVF < 0.0) IVF = 0.0; - MCpI_temp = IVF * AirDensity * CpAir; - if (MCpI_temp < 0.0) MCpI_temp = 0.0; - state.dataHeatBal->Infiltration(j).VolumeFlowRate = MCpI_temp / AirDensity / CpAir; - if (AdjustZoneInfiltrationFlowFlag && state.dataHeatBalFanSys->ZoneInfiltrationFlag(NZ)) { - if (state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment == DataHeatBalance::InfiltrationFlow::Adjust) { - if (state.dataHeatBal->Infiltration(j).MassFlowRate > 0.0) { - state.dataHeatBal->Infiltration(j).VolumeFlowRate = state.dataHeatBal->Infiltration(j).MassFlowRate / AirDensity; - MCpI_temp = state.dataHeatBal->Infiltration(j).VolumeFlowRate * AirDensity * CpAir; - } - } - if (state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment == DataHeatBalance::InfiltrationFlow::Add) { - state.dataHeatBal->Infiltration(j).VolumeFlowRate = state.dataHeatBal->Infiltration(j).VolumeFlowRate + - state.dataHeatBal->MassConservation(NZ).InfiltrationMassFlowRate / AirDensity; - MCpI_temp = state.dataHeatBal->Infiltration(j).VolumeFlowRate * AirDensity * CpAir; + if (AdjustZoneInfiltrationFlowFlag && state.dataHeatBalFanSys->ZoneInfiltrationFlag(NZ)) { + if (state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment == DataHeatBalance::InfiltrationFlow::Adjust) { + if (thisInfiltration.MassFlowRate > 0.0 || thisInfiltration.ModelType == DataHeatBalance::InfiltrationModelType::DesignFlowRate) { + // For DesignFlowRate, allow exfiltraion + thisInfiltration.VolumeFlowRate = thisInfiltration.MassFlowRate / AirDensity; + MCpI_temp = thisInfiltration.VolumeFlowRate * AirDensity * CpAir; } } - state.dataHeatBal->Infiltration(j).MassFlowRate = state.dataHeatBal->Infiltration(j).VolumeFlowRate * AirDensity; - } break; - default: - break; + if (state.dataHeatBal->ZoneAirMassFlow.InfiltrationTreatment == DataHeatBalance::InfiltrationFlow::Add) { + thisInfiltration.VolumeFlowRate = + thisInfiltration.VolumeFlowRate + state.dataHeatBal->MassConservation(NZ).InfiltrationMassFlowRate / AirDensity; + MCpI_temp = thisInfiltration.VolumeFlowRate * AirDensity * CpAir; + } } + thisInfiltration.MassFlowRate = thisInfiltration.VolumeFlowRate * AirDensity; - if (state.dataHeatBal->Infiltration(j).EMSOverrideOn) { - IVF = state.dataHeatBal->Infiltration(j).EMSAirFlowRateValue; + if (thisInfiltration.EMSOverrideOn) { + IVF = thisInfiltration.EMSAirFlowRateValue; if (IVF < 0.0) IVF = 0.0; MCpI_temp = IVF * AirDensity * CpAir; if (MCpI_temp < 0.0) MCpI_temp = 0.0; @@ -6093,26 +6209,39 @@ void CalcAirFlowSimple(EnergyPlusData &state, if (state.dataHeatBal->Zone(NZ).zoneOAQuadratureSum) { state.dataHeatBal->ZoneAirBalance(state.dataHeatBal->Zone(NZ).zoneOABalanceIndex).InfMassFlowRate += MCpI_temp / CpAir; } else { - state.dataHeatBal->Infiltration(j).MCpI_temp = MCpI_temp; - state.dataHeatBalFanSys->MCPI(NZ) += MCpI_temp; - state.dataHeatBalFanSys->OAMFL(NZ) += MCpI_temp / CpAir; - state.dataHeatBalFanSys->MCPTI(NZ) += MCpI_temp * TempExt; + thisInfiltration.MCpI_temp = MCpI_temp; + thisZoneHB.MCPI += MCpI_temp; + thisZoneHB.OAMFL += MCpI_temp / CpAir; + thisZoneHB.MCPTI += MCpI_temp * TempExt; + if (state.dataHeatBal->doSpaceHeatBalance) { + auto &thisSpaceHB = state.dataZoneTempPredictorCorrector->spaceHeatBalance(thisInfiltration.spaceIndex); + thisSpaceHB.MCPI += MCpI_temp; + thisSpaceHB.OAMFL += MCpI_temp / CpAir; + thisSpaceHB.MCPTI += MCpI_temp * TempExt; + } } } // Add infiltration rate enhanced by the existence of thermal chimney - for (int NZ = 1; NZ <= state.dataGlobal->NumOfZones; ++NZ) { - state.dataHeatBalFanSys->MCPI(NZ) += state.dataHeatBalFanSys->MCPThermChim(NZ); - state.dataHeatBalFanSys->OAMFL(NZ) += state.dataHeatBalFanSys->ThermChimAMFL(NZ); - state.dataHeatBalFanSys->MCPTI(NZ) += state.dataHeatBalFanSys->MCPTThermChim(NZ); + for (auto &thisZoneHB : state.dataZoneTempPredictorCorrector->zoneHeatBalance) { + thisZoneHB.MCPI += thisZoneHB.MCPThermChim; + thisZoneHB.OAMFL += thisZoneHB.ThermChimAMFL; + thisZoneHB.MCPTI += thisZoneHB.MCPTThermChim; + } + if (state.dataHeatBal->doSpaceHeatBalance) { + for (auto &thisSpaceHB : state.dataZoneTempPredictorCorrector->spaceHeatBalance) { + thisSpaceHB.MCPI += thisSpaceHB.MCPThermChim; + thisSpaceHB.OAMFL += thisSpaceHB.ThermChimAMFL; + thisSpaceHB.MCPTI += thisSpaceHB.MCPTThermChim; + } } // Calculate combined outdoor air flows - for (auto thisZoneAirBalance : state.dataHeatBal->ZoneAirBalance) { - if (thisZoneAirBalance.BalanceMethod == AirBalance::Quadrature) { + for (auto &thisZoneAirBalance : state.dataHeatBal->ZoneAirBalance) { + if (thisZoneAirBalance.BalanceMethod == DataHeatBalance::AirBalance::Quadrature) { if (!thisZoneAirBalance.OneTimeFlag) GetStandAloneERVNodes(state, thisZoneAirBalance); if (thisZoneAirBalance.NumOfERVs > 0) { - for (I = 1; I <= thisZoneAirBalance.NumOfERVs; ++I) { + for (int I = 1; I <= thisZoneAirBalance.NumOfERVs; ++I) { Real64 MassFlowDiff = state.dataLoopNodes->Node(thisZoneAirBalance.ERVExhaustNode(I)).MassFlowRate - state.dataLoopNodes->Node(thisZoneAirBalance.ERVInletNode(I)).MassFlowRate; if (MassFlowDiff > 0.0) { @@ -6121,17 +6250,25 @@ void CalcAirFlowSimple(EnergyPlusData &state, } } int NZ = thisZoneAirBalance.ZonePtr; - AirDensity = PsyRhoAirFnPbTdbW( + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ); + // Use air node information linked to the zone if defined + Real64 HumRatExt = 0.0; + if (state.dataHeatBal->Zone(NZ).LinkedOutAirNode > 0) { + HumRatExt = state.dataLoopNodes->Node(state.dataHeatBal->Zone(NZ).LinkedOutAirNode).HumRat; + } else { + HumRatExt = state.dataEnvrn->OutHumRat; + } + Real64 AirDensity = Psychrometrics::PsyRhoAirFnPbTdbW( state, state.dataEnvrn->OutBaroPress, state.dataHeatBal->Zone(NZ).OutDryBulbTemp, HumRatExt, RoutineNameZoneAirBalance); - CpAir = PsyCpAirFnW(HumRatExt); + Real64 CpAir = Psychrometrics::PsyCpAirFnW(HumRatExt); thisZoneAirBalance.ERVMassFlowRate *= AirDensity; - state.dataHeatBalFanSys->MDotOA(NZ) = std::sqrt(pow_2(thisZoneAirBalance.NatMassFlowRate) + pow_2(thisZoneAirBalance.IntMassFlowRate) + - pow_2(thisZoneAirBalance.ExhMassFlowRate) + pow_2(thisZoneAirBalance.ERVMassFlowRate) + - pow_2(thisZoneAirBalance.InfMassFlowRate) + - pow_2(AirDensity * thisZoneAirBalance.InducedAirRate * - GetCurrentScheduleValue(state, thisZoneAirBalance.InducedAirSchedPtr))) + - thisZoneAirBalance.BalMassFlowRate; - state.dataHeatBalFanSys->MDotCPOA(NZ) = state.dataHeatBalFanSys->MDotOA(NZ) * CpAir; + thisZoneHB.MDotOA = std::sqrt(pow_2(thisZoneAirBalance.NatMassFlowRate) + pow_2(thisZoneAirBalance.IntMassFlowRate) + + pow_2(thisZoneAirBalance.ExhMassFlowRate) + pow_2(thisZoneAirBalance.ERVMassFlowRate) + + pow_2(thisZoneAirBalance.InfMassFlowRate) + + pow_2(AirDensity * thisZoneAirBalance.InducedAirRate * + ScheduleManager::GetCurrentScheduleValue(state, thisZoneAirBalance.InducedAirSchedPtr))) + + thisZoneAirBalance.BalMassFlowRate; + thisZoneHB.MDotCPOA = thisZoneHB.MDotOA * CpAir; } } } @@ -6335,8 +6472,8 @@ void ReportZoneSizingDOASInputs(EnergyPlusData &state, // BSLLC Start // if ( sqlite ) { - // state.dataSQLiteProcedures->sqlite->addSQLiteZoneSizingRecord( ZoneName, LoadType, CalcDesLoad, UserDesLoad, CalcDesFlow, UserDesFlow, - // DesDayName, PeakHrMin, + // state.dataSQLiteProcedures->sqlite->addSQLiteZoneSizingRecord( ZoneName, LoadType, CalcDesLoad, UserDesLoad, CalcDesFlow, + // UserDesFlow, DesDayName, PeakHrMin, // PeakTemp, PeakHumRat, MinOAVolFlow, DOASHeatAddRate ); // } // BSLLC Finish diff --git a/src/EnergyPlus/ZoneEquipmentManager.hh b/src/EnergyPlus/ZoneEquipmentManager.hh index c7da88b9e3b..9724abb95f6 100644 --- a/src/EnergyPlus/ZoneEquipmentManager.hh +++ b/src/EnergyPlus/ZoneEquipmentManager.hh @@ -57,6 +57,7 @@ #include #include #include +#include #include namespace EnergyPlus { @@ -100,8 +101,21 @@ namespace ZoneEquipmentManager { void InitSystemOutputRequired(EnergyPlusData &state, int ZoneNum, bool FirstHVACIteration, bool ResetSimOrder = false); + void initOutputRequired(EnergyPlusData &state, + int const ZoneNum, + DataZoneEnergyDemands::ZoneSystemSensibleDemand &energy, + DataZoneEnergyDemands::ZoneSystemMoistureDemand &moisture, + bool const FirstHVACIteration, + bool const ResetSimOrder, + int spaceNum = 0); + void DistributeSystemOutputRequired(EnergyPlusData &state, int ZoneNum, bool FirstHVACIteration); + void distributeOutputRequired(EnergyPlusData &state, + int const ZoneNum, + DataZoneEnergyDemands::ZoneSystemSensibleDemand &energy, + DataZoneEnergyDemands::ZoneSystemMoistureDemand &moisture); + void UpdateSystemOutputRequired(EnergyPlusData &state, int ZoneNum, Real64 SysOutputProvided, // sensible output provided by zone equipment (W) diff --git a/src/EnergyPlus/ZonePlenum.cc b/src/EnergyPlus/ZonePlenum.cc index 70c5a4048af..3a9d8bba451 100644 --- a/src/EnergyPlus/ZonePlenum.cc +++ b/src/EnergyPlus/ZonePlenum.cc @@ -349,6 +349,10 @@ void GetZonePlenumInput(EnergyPlusData &state) // Insert the Plenum Zone Number into the Zone Heat Balance data structure for later reference state.dataHeatBal->Zone(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ActualZoneNum).SystemZoneNodeNumber = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZoneNodeNum; + // SpaceHB TODO: For now, assign the same system node to the spaces in the zone + for (int spaceNum : state.dataHeatBal->Zone(state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ActualZoneNum).spaceIndexes) { + state.dataHeatBal->space(spaceNum).SystemZoneNodeNumber = state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).ZoneNodeNum; + } state.dataZonePlenum->ZoneRetPlenCond(ZonePlenumNum).OutletNode = GetOnlySingleNode(state, @@ -580,6 +584,10 @@ void GetZonePlenumInput(EnergyPlusData &state) // Insert the Plenum Zone Number into the Zone Heat Balance data structure for later reference state.dataHeatBal->Zone(state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ActualZoneNum).SystemZoneNodeNumber = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZoneNodeNum; + // SpaceHB TODO: For now, assign the same system node to the spaces in the zone + for (int spaceNum : state.dataHeatBal->Zone(state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ActualZoneNum).spaceIndexes) { + state.dataHeatBal->space(spaceNum).SystemZoneNodeNumber = state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).ZoneNodeNum; + } state.dataZonePlenum->ZoneSupPlenCond(ZonePlenumNum).InletNode = GetOnlySingleNode(state, diff --git a/src/EnergyPlus/ZoneTempPredictorCorrector.cc b/src/EnergyPlus/ZoneTempPredictorCorrector.cc index 21a1e051cd7..7d59e1d6403 100644 --- a/src/EnergyPlus/ZoneTempPredictorCorrector.cc +++ b/src/EnergyPlus/ZoneTempPredictorCorrector.cc @@ -69,6 +69,7 @@ #include #include #include +#include #include #include #include @@ -118,17 +119,6 @@ namespace EnergyPlus::ZoneTempPredictorCorrector { // "Predict" step is used to get zone loads for HVAC equipment // "correct" step determines zone air temp with available HVAC -// Using/Aliasing -using namespace DataHVACGlobals; -using namespace DataHeatBalance; -using namespace DataHeatBalFanSys; -using namespace Psychrometrics; -using namespace DataRoomAirModel; -using namespace DataZoneControls; -using namespace FaultsManager; -using namespace HybridModel; -using ScheduleManager::GetCurrentScheduleValue; - enum class ZoneControlTypes { Invalid = -1, @@ -237,7 +227,7 @@ void ManageZoneAirUpdates(EnergyPlusData &state, PredictSystemLoads(state, ShortenTimeStepSys, UseZoneTimeStepHistory, PriorTimeStep); } break; case DataHeatBalFanSys::PredictorCorrectorCtrl::CorrectStep: { - CorrectZoneAirTemp(state, ZoneTempChange, UseZoneTimeStepHistory); + ZoneTempChange = correctZoneAirTemps(state, UseZoneTimeStepHistory); } break; case DataHeatBalFanSys::PredictorCorrectorCtrl::RevertZoneTimestepHistories: { RevertZoneTimestepHistories(state); @@ -434,8 +424,8 @@ void GetZoneAirSetPoints(EnergyPlusData &state) if (TStatObjects(Item).ZoneListActive) { cAlphaArgs(2) = Zone(ZoneList(TStatObjects(Item).ZoneOrZoneListPtr).Zone(Item1)).Name; } - int ZoneAssigned = - UtilityRoutines::FindItemInList(cAlphaArgs(2), TempControlledZone, &ZoneTempControls::ZoneName, TempControlledZoneNum - 1); + int ZoneAssigned = UtilityRoutines::FindItemInList( + cAlphaArgs(2), TempControlledZone, &DataZoneControls::ZoneTempControls::ZoneName, TempControlledZoneNum - 1); if (ZoneAssigned == 0) { TempControlledZone(TempControlledZoneNum).ZoneName = cAlphaArgs(2); TempControlledZone(TempControlledZoneNum).ActualZoneNum = UtilityRoutines::FindItemInList(cAlphaArgs(2), Zone); @@ -932,6 +922,8 @@ void GetZoneAirSetPoints(EnergyPlusData &state) ShowSevereError( state, cCurrentModuleObject + "=\"" + cAlphaArgs(1) + " invalid " + cAlphaFieldNames(2) + "=\"" + cAlphaArgs(2) + "\" not found."); ErrorsFound = true; + } else { + state.dataHeatBal->Zone(HumidityControlZone(HumidControlledZoneNum).ActualZoneNum).humidityControlZoneIndex = HumidControlledZoneNum; } HumidityControlZone(HumidControlledZoneNum).HumidifyingSched = cAlphaArgs(3); HumidityControlZone(HumidControlledZoneNum).HumidifyingSchedIndex = GetScheduleIndex(state, cAlphaArgs(3)); @@ -1034,7 +1026,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) cAlphaArgs(2) = state.dataHeatBal->Zone(ZoneList(ComfortTStatObjects(Item).ZoneOrZoneListPtr).Zone(Item1)).Name; } int ZoneAssigned = UtilityRoutines::FindItemInList( - cAlphaArgs(2), ComfortControlledZone, &ZoneComfortControls::ZoneName, ComfortControlledZoneNum - 1); + cAlphaArgs(2), ComfortControlledZone, &DataZoneControls::ZoneComfortControls::ZoneName, ComfortControlledZoneNum - 1); if (ZoneAssigned == 0) { ComfortControlledZone(ComfortControlledZoneNum).ZoneName = cAlphaArgs(2); ComfortControlledZone(ComfortControlledZoneNum).ActualZoneNum = UtilityRoutines::FindItemInList(cAlphaArgs(2), Zone); @@ -1711,7 +1703,7 @@ void GetZoneAirSetPoints(EnergyPlusData &state) if (allocated(TComfortControlTypes)) TComfortControlTypes.deallocate(); // Get the Hybrid Model setting inputs - GetHybridModelZone(state); + HybridModel::GetHybridModelZone(state); // Default multiplier values Real64 ZoneVolCapMultpSens = 1.0; @@ -2333,8 +2325,8 @@ void GetZoneAirSetPoints(EnergyPlusData &state) cAlphaArgs(2) = state.dataHeatBal->Zone(ZoneList(state.dataZoneCtrls->StagedTStatObjects(Item).ZoneOrZoneListPtr).Zone(Item1)).Name; } - int ZoneAssigned = - UtilityRoutines::FindItemInList(cAlphaArgs(2), StageControlledZone, &ZoneStagedControls::ZoneName, StageControlledZoneNum - 1); + int ZoneAssigned = UtilityRoutines::FindItemInList( + cAlphaArgs(2), StageControlledZone, &DataZoneControls::ZoneStagedControls::ZoneName, StageControlledZoneNum - 1); if (ZoneAssigned == 0) { StageControlledZone(StageControlledZoneNum).ZoneName = cAlphaArgs(2); StageControlledZone(StageControlledZoneNum).ActualZoneNum = UtilityRoutines::FindItemInList(cAlphaArgs(2), Zone); @@ -2732,13 +2724,9 @@ void InitZoneAirSetPoints(EnergyPlusData &state) static constexpr std::string_view RoutineName("InitZoneAirSetpoints: "); // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - int Loop; - int ZoneNum; bool FirstSurfFlag; int TRefFlag; // Flag for Reference Temperature process in Zones - int SurfNum; - auto &Zone = state.dataHeatBal->Zone; auto &ZoneList = state.dataHeatBal->ZoneList; auto &TempControlledZone = state.dataZoneCtrls->TempControlledZone; auto &TempZoneThermostatSetPoint = state.dataHeatBalFanSys->TempZoneThermostatSetPoint; @@ -2748,8 +2736,6 @@ void InitZoneAirSetPoints(EnergyPlusData &state) auto &ZoneThermostatSetPointLo = state.dataHeatBalFanSys->ZoneThermostatSetPointLo; auto &ZoneThermostatSetPointHi = state.dataHeatBalFanSys->ZoneThermostatSetPointHi; auto &NumOfZones = state.dataGlobal->NumOfZones; - auto &ZoneSysEnergyDemand = state.dataZoneEnergyDemand->ZoneSysEnergyDemand; - auto &ZoneSysMoistureDemand = state.dataZoneEnergyDemand->ZoneSysMoistureDemand; if (state.dataZoneTempPredictorCorrector->InitZoneAirSetPointsOneTimeFlag) { TempZoneThermostatSetPoint.dimension(NumOfZones, 0.0); @@ -2767,41 +2753,9 @@ void InitZoneAirSetPoints(EnergyPlusData &state) state.dataHeatBalFanSys->ComfortControlTypeRpt.dimension(NumOfZones, 0); state.dataHeatBalFanSys->ZoneComfortControlsFanger.allocate(NumOfZones); } - state.dataZoneTempPredictorCorrector->ZoneSetPointLast.dimension(NumOfZones, 0.0); state.dataZoneEnergyDemand->Setback.dimension(NumOfZones, false); state.dataZoneEnergyDemand->DeadBandOrSetback.dimension(NumOfZones, false); state.dataZoneEnergyDemand->CurDeadBandOrSetback.dimension(NumOfZones, false); - state.dataHeatBal->ZoneSNLoadHeatEnergy.dimension(NumOfZones, 0.0); - state.dataHeatBal->ZoneSNLoadCoolEnergy.dimension(NumOfZones, 0.0); - state.dataHeatBal->ZoneSNLoadHeatRate.dimension(NumOfZones, 0.0); - state.dataHeatBal->ZoneSNLoadCoolRate.dimension(NumOfZones, 0.0); - state.dataHeatBal->ZoneSNLoadPredictedRate.dimension(NumOfZones, 0.0); - state.dataHeatBal->ZoneSNLoadPredictedHSPRate.dimension(NumOfZones, 0.0); - state.dataHeatBal->ZoneSNLoadPredictedCSPRate.dimension(NumOfZones, 0.0); - state.dataHeatBal->latentReports.allocate(NumOfZones); - state.dataHeatBalFanSys->WZoneTimeMinus1.dimension(NumOfZones, 0.0); - state.dataHeatBalFanSys->WZoneTimeMinus2.dimension(NumOfZones, 0.0); - state.dataHeatBalFanSys->WZoneTimeMinus3.dimension(NumOfZones, 0.0); - state.dataHeatBalFanSys->WZoneTimeMinus4.dimension(NumOfZones, 0.0); - state.dataHeatBalFanSys->DSWZoneTimeMinus1.dimension(NumOfZones, 0.0); - state.dataHeatBalFanSys->DSWZoneTimeMinus2.dimension(NumOfZones, 0.0); - state.dataHeatBalFanSys->DSWZoneTimeMinus3.dimension(NumOfZones, 0.0); - state.dataHeatBalFanSys->DSWZoneTimeMinus4.dimension(NumOfZones, 0.0); - state.dataHeatBalFanSys->ZoneAirHumRatTemp.dimension(NumOfZones, 0.0); - state.dataHeatBalFanSys->WZoneTimeMinus1Temp.dimension(NumOfZones, 0.0); - state.dataHeatBalFanSys->WZoneTimeMinus2Temp.dimension(NumOfZones, 0.0); - state.dataHeatBalFanSys->WZoneTimeMinus3Temp.dimension(NumOfZones, 0.0); - state.dataHeatBalFanSys->WZoneTimeMinusP.dimension(NumOfZones, 0.0); - state.dataZoneTempPredictorCorrector->TempIndZnLd.dimension(NumOfZones, 0.0); - state.dataZoneTempPredictorCorrector->TempDepZnLd.dimension(NumOfZones, 0.0); - state.dataHeatBalFanSys->NonAirSystemResponse.dimension(NumOfZones, 0.0); - state.dataHeatBalFanSys->SysDepZoneLoads.dimension(NumOfZones, 0.0); - state.dataHeatBalFanSys->SysDepZoneLoadsLagged.dimension(NumOfZones, 0.0); - state.dataZoneTempPredictorCorrector->ZoneAirRelHum.dimension(NumOfZones, 0.0); - state.dataHeatBalFanSys->ZoneWMX.dimension(NumOfZones, 0.0); - state.dataHeatBalFanSys->ZoneWM2.dimension(NumOfZones, 0.0); - state.dataHeatBalFanSys->ZoneT1.dimension(NumOfZones, 0.0); - state.dataHeatBalFanSys->ZoneW1.dimension(NumOfZones, 0.0); state.dataHeatBal->ZoneListSNLoadHeatEnergy.dimension(state.dataHeatBal->NumOfZoneLists, 0.0); state.dataHeatBal->ZoneListSNLoadCoolEnergy.dimension(state.dataHeatBal->NumOfZoneLists, 0.0); @@ -2812,10 +2766,6 @@ void InitZoneAirSetPoints(EnergyPlusData &state) state.dataHeatBal->ZoneGroupSNLoadCoolEnergy.dimension(state.dataHeatBal->NumOfZoneGroups, 0.0); state.dataHeatBal->ZoneGroupSNLoadHeatRate.dimension(state.dataHeatBal->NumOfZoneGroups, 0.0); state.dataHeatBal->ZoneGroupSNLoadCoolRate.dimension(state.dataHeatBal->NumOfZoneGroups, 0.0); - state.dataHeatBalFanSys->AIRRAT.dimension(NumOfZones, 0.0); - state.dataHeatBalFanSys->ZTM1.dimension(NumOfZones, 0.0); - state.dataHeatBalFanSys->ZTM2.dimension(NumOfZones, 0.0); - state.dataHeatBalFanSys->ZTM3.dimension(NumOfZones, 0.0); // Hybrid modeling state.dataHeatBalFanSys->PreviousMeasuredZT1.dimension(NumOfZones, 0.0); @@ -2826,319 +2776,147 @@ void InitZoneAirSetPoints(EnergyPlusData &state) state.dataHeatBalFanSys->PreviousMeasuredHumRat3.dimension(NumOfZones, 0.0); // Allocate Derived Types - ZoneSysEnergyDemand.allocate(NumOfZones); - ZoneSysMoistureDemand.allocate(NumOfZones); + state.dataZoneEnergyDemand->ZoneSysEnergyDemand.allocate(NumOfZones); + state.dataZoneEnergyDemand->ZoneSysMoistureDemand.allocate(NumOfZones); + if (state.dataHeatBal->doSpaceHeatBalanceSimulation || state.dataHeatBal->doSpaceHeatBalanceSizing) { + state.dataZoneEnergyDemand->spaceSysEnergyDemand.allocate(state.dataGlobal->numSpaces); + state.dataZoneEnergyDemand->spaceSysMoistureDemand.allocate(state.dataGlobal->numSpaces); + } - for (Loop = 1; Loop <= NumOfZones; ++Loop) { + for (int zoneNum = 1; zoneNum <= NumOfZones; ++zoneNum) { FirstSurfFlag = true; - for (SurfNum = Zone(Loop).HTSurfaceFirst; SurfNum <= Zone(Loop).HTSurfaceLast; ++SurfNum) { - if (FirstSurfFlag) { - TRefFlag = state.dataSurface->SurfTAirRef(SurfNum); - FirstSurfFlag = false; - } - // for each particular zone, the reference air temperature(s) should be the same - // (either mean air, bulk air, or supply air temp). - if (state.dataSurface->SurfTAirRef(SurfNum) != TRefFlag) { - ShowWarningError(state, "Different reference air temperatures for difference surfaces encountered in zone " + Zone(Loop).Name); + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + auto &thisSpace = state.dataHeatBal->space(spaceNum); + for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { + if (FirstSurfFlag) { + TRefFlag = state.dataSurface->SurfTAirRef(SurfNum); + FirstSurfFlag = false; + } + // for each particular zone, the reference air temperature(s) should be the same + // (either mean air, bulk air, or supply air temp). + if (state.dataSurface->SurfTAirRef(SurfNum) != TRefFlag) { + ShowWarningError(state, + "Different reference air temperatures for difference surfaces encountered in zone " + + state.dataHeatBal->Zone(zoneNum).Name); + } } } } // CurrentModuleObject='Zone' - for (Loop = 1; Loop <= NumOfZones; ++Loop) { - SetupOutputVariable(state, - "Zone Air System Sensible Heating Energy", - OutputProcessor::Unit::J, - state.dataHeatBal->ZoneSNLoadHeatEnergy(Loop), - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Summed, - Zone(Loop).Name, - _, - "ENERGYTRANSFER", - "Heating", - _, - "Building", - Zone(Loop).Name, - Zone(Loop).Multiplier, - Zone(Loop).ListMultiplier); - SetupOutputVariable(state, - "Zone Air System Sensible Cooling Energy", - OutputProcessor::Unit::J, - state.dataHeatBal->ZoneSNLoadCoolEnergy(Loop), - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Summed, - Zone(Loop).Name, - _, - "ENERGYTRANSFER", - "Cooling", - _, - "Building", - Zone(Loop).Name, - Zone(Loop).Multiplier, - Zone(Loop).ListMultiplier); - SetupOutputVariable(state, - "Zone Air System Sensible Heating Rate", - OutputProcessor::Unit::W, - state.dataHeatBal->ZoneSNLoadHeatRate(Loop), - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); - SetupOutputVariable(state, - "Zone Air System Sensible Cooling Rate", - OutputProcessor::Unit::W, - state.dataHeatBal->ZoneSNLoadCoolRate(Loop), - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); - if (state.dataHeatBal->DoLatentSizing) { - SetupOutputVariable(state, - "Zone Air System Latent Heating Energy", - OutputProcessor::Unit::J, - state.dataHeatBal->latentReports(Loop).ZoneLTLoadHeatEnergy, - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Summed, - Zone(Loop).Name); - SetupOutputVariable(state, - "Zone Air System Latent Cooling Energy", - OutputProcessor::Unit::J, - state.dataHeatBal->latentReports(Loop).ZoneLTLoadCoolEnergy, - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Summed, - Zone(Loop).Name); - SetupOutputVariable(state, - "Zone Air System Latent Heating Rate", - OutputProcessor::Unit::W, - state.dataHeatBal->latentReports(Loop).ZoneLTLoadHeatRate, - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); - SetupOutputVariable(state, - "Zone Air System Latent Cooling Rate", - OutputProcessor::Unit::W, - state.dataHeatBal->latentReports(Loop).ZoneLTLoadCoolRate, - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); - // temporarily hide these behind DoLatentSizing flag - SetupOutputVariable(state, - "Zone Air System Sensible Heat Ratio", - OutputProcessor::Unit::None, - state.dataHeatBal->latentReports(Loop).ZoneSensibleHeatRatio, - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); - SetupOutputVariable(state, - "Zone Air Vapor Pressure Difference", - OutputProcessor::Unit::Pa, - state.dataHeatBal->latentReports(Loop).ZoneVaporPressureDifference, - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); + for (int zoneNum = 1; zoneNum <= NumOfZones; ++zoneNum) { + auto &thisZone = state.dataHeatBal->Zone(zoneNum); + state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum).setUpOutputVars(state, DataStringGlobals::zonePrefix, thisZone.Name); + if (state.dataHeatBal->doSpaceHeatBalanceSizing || state.dataHeatBal->doSpaceHeatBalanceSimulation) { + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).setUpOutputVars( + state, DataStringGlobals::spacePrefix, state.dataHeatBal->space(spaceNum).Name); + } + } + bool staged = false; + if (allocated(state.dataZoneCtrls->StageZoneLogic)) { + staged = state.dataZoneCtrls->StageZoneLogic(zoneNum); + } + // If not doSpaceHeatBalanceSimulation then meter zones, not spaces + bool attachMeters = !state.dataHeatBal->doSpaceHeatBalanceSimulation; + state.dataZoneEnergyDemand->ZoneSysEnergyDemand(zoneNum).setUpOutputVars( + state, DataStringGlobals::zonePrefix, thisZone.Name, staged, attachMeters, thisZone.Multiplier, thisZone.ListMultiplier); + if (state.dataHeatBal->doSpaceHeatBalanceSizing || state.dataHeatBal->doSpaceHeatBalanceSimulation) { + // If doSpaceHeatBalanceSimulation then meter spaces, not zones + attachMeters = state.dataHeatBal->doSpaceHeatBalanceSimulation; + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + state.dataZoneEnergyDemand->spaceSysEnergyDemand(spaceNum).setUpOutputVars(state, + DataStringGlobals::spacePrefix, + state.dataHeatBal->space(spaceNum).Name, + staged, + attachMeters, + thisZone.Multiplier, + thisZone.ListMultiplier); + } + } + state.dataZoneEnergyDemand->ZoneSysMoistureDemand(zoneNum).setUpOutputVars(state, DataStringGlobals::zonePrefix, thisZone.Name); + if (state.dataHeatBal->doSpaceHeatBalanceSizing || state.dataHeatBal->doSpaceHeatBalanceSimulation) { + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + state.dataZoneEnergyDemand->spaceSysMoistureDemand(spaceNum).setUpOutputVars( + state, DataStringGlobals::spacePrefix, state.dataHeatBal->space(spaceNum).Name); + } } - SetupOutputVariable(state, - "Zone Air Temperature", - OutputProcessor::Unit::C, - state.dataHeatBalFanSys->ZT(Loop), - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); SetupOutputVariable(state, "Zone Thermostat Air Temperature", OutputProcessor::Unit::C, - state.dataHeatBalFanSys->TempTstatAir(Loop), - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); - SetupOutputVariable(state, - "Zone Air Humidity Ratio", - OutputProcessor::Unit::None, - state.dataHeatBalFanSys->ZoneAirHumRat(Loop), - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); - SetupOutputVariable(state, - "Zone Air Relative Humidity", - OutputProcessor::Unit::Perc, - state.dataZoneTempPredictorCorrector->ZoneAirRelHum(Loop), - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); - - // The following output variables are for the predicted Heating/Cooling load for the zone which can be compared to actual load. - // There are two sets of data available: one where zone and group multipliers have been applied and another where the multipliers have - // not. First, these report variables are NOT multiplied by zone and group multipliers - SetupOutputVariable(state, - "Zone Predicted Sensible Load to Setpoint Heat Transfer Rate", - OutputProcessor::Unit::W, - state.dataHeatBal->ZoneSNLoadPredictedRate(Loop), - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); - SetupOutputVariable(state, - "Zone Predicted Sensible Load to Heating Setpoint Heat Transfer Rate", - OutputProcessor::Unit::W, - state.dataHeatBal->ZoneSNLoadPredictedHSPRate(Loop), - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); - SetupOutputVariable(state, - "Zone Predicted Sensible Load to Cooling Setpoint Heat Transfer Rate", - OutputProcessor::Unit::W, - state.dataHeatBal->ZoneSNLoadPredictedCSPRate(Loop), - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); - // Second, these report variable ARE multiplied by zone and group multipliers - SetupOutputVariable(state, - "Zone System Predicted Sensible Load to Setpoint Heat Transfer Rate", - OutputProcessor::Unit::W, - ZoneSysEnergyDemand(Loop).TotalOutputRequired, - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); - SetupOutputVariable(state, - "Zone System Predicted Sensible Load to Heating Setpoint Heat Transfer Rate", - OutputProcessor::Unit::W, - ZoneSysEnergyDemand(Loop).OutputRequiredToHeatingSP, - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); - SetupOutputVariable(state, - "Zone System Predicted Sensible Load to Cooling Setpoint Heat Transfer Rate", - OutputProcessor::Unit::W, - ZoneSysEnergyDemand(Loop).OutputRequiredToCoolingSP, - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); - - // The following output variables are for the predicted moisture load for the zone with humidity controlled specified. - // There are two sets of data available: one where zone and group multipliers have been applied and another where the multipliers have - // not. First, these report variables are NOT multiplied by zone and group multipliers - SetupOutputVariable(state, - "Zone Predicted Moisture Load Moisture Transfer Rate", - OutputProcessor::Unit::kgWater_s, - state.dataHeatBal->latentReports(Loop).ZoneMoisturePredictedRate, - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); - SetupOutputVariable(state, - "Zone Predicted Moisture Load to Humidifying Setpoint Moisture Transfer Rate", - OutputProcessor::Unit::kgWater_s, - state.dataHeatBal->latentReports(Loop).ZoneMoisturePredictedHumSPRate, - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); - SetupOutputVariable(state, - "Zone Predicted Moisture Load to Dehumidifying Setpoint Moisture Transfer Rate", - OutputProcessor::Unit::kgWater_s, - state.dataHeatBal->latentReports(Loop).ZoneMoisturePredictedDehumSPRate, - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); - // Second, these report variable ARE multiplied by zone and group multipliers - SetupOutputVariable(state, - "Zone System Predicted Moisture Load Moisture Transfer Rate", - OutputProcessor::Unit::kgWater_s, - ZoneSysMoistureDemand(Loop).TotalOutputRequired, - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); - SetupOutputVariable(state, - "Zone System Predicted Moisture Load to Humidifying Setpoint Moisture Transfer Rate", - OutputProcessor::Unit::kgWater_s, - ZoneSysMoistureDemand(Loop).OutputRequiredToHumidifyingSP, - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); - SetupOutputVariable(state, - "Zone System Predicted Moisture Load to Dehumidifying Setpoint Moisture Transfer Rate", - OutputProcessor::Unit::kgWater_s, - ZoneSysMoistureDemand(Loop).OutputRequiredToDehumidifyingSP, + state.dataHeatBalFanSys->TempTstatAir(zoneNum), OutputProcessor::SOVTimeStepType::System, OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); - + thisZone.Name); SetupOutputVariable(state, "Zone Thermostat Control Type", OutputProcessor::Unit::None, - TempControlTypeRpt(Loop), + TempControlTypeRpt(zoneNum), OutputProcessor::SOVTimeStepType::Zone, OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); + thisZone.Name); SetupOutputVariable(state, "Zone Thermostat Heating Setpoint Temperature", OutputProcessor::Unit::C, - ZoneThermostatSetPointLo(Loop), + ZoneThermostatSetPointLo(zoneNum), OutputProcessor::SOVTimeStepType::System, OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); + thisZone.Name); SetupOutputVariable(state, "Zone Thermostat Cooling Setpoint Temperature", OutputProcessor::Unit::C, - ZoneThermostatSetPointHi(Loop), + ZoneThermostatSetPointHi(zoneNum), OutputProcessor::SOVTimeStepType::System, OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); + thisZone.Name); SetupOutputVariable(state, "Zone Adaptive Comfort Operative Temperature Set Point", OutputProcessor::Unit::C, - state.dataHeatBalFanSys->AdapComfortCoolingSetPoint(Loop), + state.dataHeatBalFanSys->AdapComfortCoolingSetPoint(zoneNum), OutputProcessor::SOVTimeStepType::Zone, OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); + thisZone.Name); SetupOutputVariable(state, "Zone Predicted Sensible Load Room Air Correction Factor", OutputProcessor::Unit::None, - state.dataHeatBalFanSys->LoadCorrectionFactor(Loop), + state.dataHeatBalFanSys->LoadCorrectionFactor(zoneNum), OutputProcessor::SOVTimeStepType::System, OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); - - if (allocated(state.dataZoneCtrls->StageZoneLogic)) { - if (state.dataZoneCtrls->StageZoneLogic(Loop)) { - SetupOutputVariable(state, - "Zone Thermostat Staged Number", - OutputProcessor::Unit::None, - ZoneSysEnergyDemand(Loop).StageNum, - OutputProcessor::SOVTimeStepType::System, - OutputProcessor::SOVStoreType::Average, - Zone(Loop).Name); - } - } - - } // Loop + thisZone.Name); + } // zoneNum // Thermal comfort control output if (state.dataZoneCtrls->NumComfortControlledZones > 0) { // CurrentModuleObject='ZoneControl:Thermostat:ThermalComfort' - for (Loop = 1; Loop <= state.dataZoneCtrls->NumComfortControlledZones; ++Loop) { - ZoneNum = ComfortControlledZone(Loop).ActualZoneNum; + for (int Loop = 1; Loop <= state.dataZoneCtrls->NumComfortControlledZones; ++Loop) { + int zoneNum = ComfortControlledZone(Loop).ActualZoneNum; + auto &thisZone = state.dataHeatBal->Zone(zoneNum); SetupOutputVariable(state, "Zone Thermal Comfort Control Type", OutputProcessor::Unit::None, - state.dataHeatBalFanSys->ComfortControlTypeRpt(ZoneNum), + state.dataHeatBalFanSys->ComfortControlTypeRpt(zoneNum), OutputProcessor::SOVTimeStepType::Zone, OutputProcessor::SOVStoreType::Average, - Zone(ZoneNum).Name); + thisZone.Name); SetupOutputVariable(state, "Zone Thermal Comfort Control Fanger Low Setpoint PMV", OutputProcessor::Unit::None, - state.dataHeatBalFanSys->ZoneComfortControlsFanger(ZoneNum).LowPMV, + state.dataHeatBalFanSys->ZoneComfortControlsFanger(zoneNum).LowPMV, OutputProcessor::SOVTimeStepType::Zone, OutputProcessor::SOVStoreType::Average, - Zone(ZoneNum).Name); + thisZone.Name); SetupOutputVariable(state, "Zone Thermal Comfort Control Fanger High Setpoint PMV", OutputProcessor::Unit::None, - state.dataHeatBalFanSys->ZoneComfortControlsFanger(ZoneNum).HighPMV, + state.dataHeatBalFanSys->ZoneComfortControlsFanger(zoneNum).HighPMV, OutputProcessor::SOVTimeStepType::Zone, OutputProcessor::SOVStoreType::Average, - Zone(ZoneNum).Name); + thisZone.Name); } } // CurrentModuleObject='ZoneList' - for (Loop = 1; Loop <= state.dataHeatBal->NumOfZoneLists; ++Loop) { + for (int Loop = 1; Loop <= state.dataHeatBal->NumOfZoneLists; ++Loop) { SetupOutputVariable(state, "Zone List Sensible Heating Energy", OutputProcessor::Unit::J, @@ -3170,7 +2948,7 @@ void InitZoneAirSetPoints(EnergyPlusData &state) } // Loop // CurrentModuleObject='ZoneGroup' - for (Loop = 1; Loop <= state.dataHeatBal->NumOfZoneGroups; ++Loop) { + for (int Loop = 1; Loop <= state.dataHeatBal->NumOfZoneGroups; ++Loop) { SetupOutputVariable(state, "Zone Group Sensible Heating Energy", OutputProcessor::Unit::J, @@ -3206,23 +2984,14 @@ void InitZoneAirSetPoints(EnergyPlusData &state) // Do the Begin Environment initializations if (state.dataZoneTempPredictorCorrector->MyEnvrnFlag && state.dataGlobal->BeginEnvrnFlag) { - state.dataHeatBalFanSys->AIRRAT = 0.0; - state.dataHeatBalFanSys->ZTM1 = 0.0; - state.dataHeatBalFanSys->ZTM2 = 0.0; - state.dataHeatBalFanSys->ZTM3 = 0.0; - state.dataHeatBalFanSys->WZoneTimeMinus1 = state.dataEnvrn->OutHumRat; - state.dataHeatBalFanSys->WZoneTimeMinus2 = state.dataEnvrn->OutHumRat; - state.dataHeatBalFanSys->WZoneTimeMinus3 = state.dataEnvrn->OutHumRat; - state.dataHeatBalFanSys->WZoneTimeMinus4 = state.dataEnvrn->OutHumRat; - state.dataHeatBalFanSys->WZoneTimeMinusP = state.dataEnvrn->OutHumRat; - state.dataHeatBalFanSys->DSWZoneTimeMinus1 = state.dataEnvrn->OutHumRat; - state.dataHeatBalFanSys->DSWZoneTimeMinus2 = state.dataEnvrn->OutHumRat; - state.dataHeatBalFanSys->DSWZoneTimeMinus3 = state.dataEnvrn->OutHumRat; - state.dataHeatBalFanSys->DSWZoneTimeMinus4 = state.dataEnvrn->OutHumRat; - state.dataHeatBalFanSys->WZoneTimeMinus1Temp = 0.0; - state.dataHeatBalFanSys->WZoneTimeMinus2Temp = 0.0; - state.dataHeatBalFanSys->WZoneTimeMinus3Temp = 0.0; - state.dataHeatBalFanSys->ZoneAirHumRatTemp = 0.0; + for (auto &thisZoneHB : state.dataZoneTempPredictorCorrector->zoneHeatBalance) { + thisZoneHB.beginEnvironmentInit(state); + } + if (state.dataHeatBal->doSpaceHeatBalance) { + for (auto &thisSpaceHB : state.dataZoneTempPredictorCorrector->spaceHeatBalance) { + thisSpaceHB.beginEnvironmentInit(state); + } + } TempZoneThermostatSetPoint = 0.0; state.dataHeatBalFanSys->AdapComfortCoolingSetPoint = 0.0; ZoneThermostatSetPointHi = 0.0; @@ -3230,58 +2999,25 @@ void InitZoneAirSetPoints(EnergyPlusData &state) state.dataHeatBalFanSys->LoadCorrectionFactor = 1.0; TempControlType = DataHVACGlobals::ThermostatType::Uncontrolled; - for (auto &e : ZoneSysEnergyDemand) { - e.RemainingOutputRequired = 0.0; - e.TotalOutputRequired = 0.0; - } - for (auto &e : ZoneSysMoistureDemand) { - e.RemainingOutputRequired = 0.0; - e.TotalOutputRequired = 0.0; - } - for (ZoneNum = 1; ZoneNum <= NumOfZones; ++ZoneNum) { - if (allocated(ZoneSysEnergyDemand(ZoneNum).SequencedOutputRequired)) ZoneSysEnergyDemand(ZoneNum).SequencedOutputRequired = 0.0; - if (allocated(ZoneSysEnergyDemand(ZoneNum).SequencedOutputRequiredToHeatingSP)) - ZoneSysEnergyDemand(ZoneNum).SequencedOutputRequiredToHeatingSP = 0.0; - if (allocated(ZoneSysEnergyDemand(ZoneNum).SequencedOutputRequiredToCoolingSP)) - ZoneSysEnergyDemand(ZoneNum).SequencedOutputRequiredToCoolingSP = 0.0; - if (allocated(ZoneSysMoistureDemand(ZoneNum).SequencedOutputRequired)) ZoneSysMoistureDemand(ZoneNum).SequencedOutputRequired = 0.0; - if (allocated(ZoneSysMoistureDemand(ZoneNum).SequencedOutputRequiredToHumidSP)) - ZoneSysMoistureDemand(ZoneNum).SequencedOutputRequiredToHumidSP = 0.0; - if (allocated(ZoneSysMoistureDemand(ZoneNum).SequencedOutputRequiredToDehumidSP)) - ZoneSysMoistureDemand(ZoneNum).SequencedOutputRequiredToDehumidSP = 0.0; - // seems these don't need to be initialized since they are calculated each time step? - state.dataHeatBal->latentReports(ZoneNum).ZoneLTLoadHeatEnergy = 0.0; - state.dataHeatBal->latentReports(ZoneNum).ZoneLTLoadCoolEnergy = 0.0; - state.dataHeatBal->latentReports(ZoneNum).ZoneLTLoadHeatRate = 0.0; - state.dataHeatBal->latentReports(ZoneNum).ZoneLTLoadCoolRate = 0.0; - state.dataHeatBal->latentReports(ZoneNum).ZoneSensibleHeatRatio = 0.0; - state.dataHeatBal->latentReports(ZoneNum).ZoneVaporPressureDifference = 0.0; - state.dataHeatBal->latentReports(ZoneNum).ZoneMoisturePredictedRate = 0.0; - state.dataHeatBal->latentReports(ZoneNum).ZoneMoisturePredictedHumSPRate = 0.0; - state.dataHeatBal->latentReports(ZoneNum).ZoneMoisturePredictedDehumSPRate = 0.0; + for (auto &e : state.dataZoneEnergyDemand->ZoneSysEnergyDemand) { + e.beginEnvironmentInit(); + } + for (auto &e : state.dataZoneEnergyDemand->ZoneSysMoistureDemand) { + e.beginEnvironmentInit(); + } + if (state.dataHeatBal->doSpaceHeatBalance) { + for (auto &e : state.dataZoneEnergyDemand->spaceSysEnergyDemand) { + e.beginEnvironmentInit(); + } + for (auto &e : state.dataZoneEnergyDemand->spaceSysMoistureDemand) { + e.beginEnvironmentInit(); + } } state.dataZoneEnergyDemand->DeadBandOrSetback = false; - state.dataHeatBal->ZoneSNLoadHeatEnergy = 0.0; - state.dataHeatBal->ZoneSNLoadCoolEnergy = 0.0; - state.dataHeatBal->ZoneSNLoadHeatRate = 0.0; - state.dataHeatBal->ZoneSNLoadCoolRate = 0.0; - state.dataHeatBal->ZoneSNLoadPredictedRate = 0.0; - state.dataHeatBal->ZoneSNLoadPredictedHSPRate = 0.0; - state.dataHeatBal->ZoneSNLoadPredictedCSPRate = 0.0; - - state.dataZoneTempPredictorCorrector->TempIndZnLd = 0.0; - state.dataZoneTempPredictorCorrector->TempDepZnLd = 0.0; - state.dataHeatBalFanSys->NonAirSystemResponse = 0.0; - state.dataHeatBalFanSys->SysDepZoneLoads = 0.0; - state.dataHeatBalFanSys->SysDepZoneLoadsLagged = 0.0; - state.dataZoneTempPredictorCorrector->ZoneAirRelHum = 0.0; - for (auto &e : Zone) + + for (auto &e : state.dataHeatBal->Zone) e.NoHeatToReturnAir = false; - state.dataHeatBalFanSys->ZoneT1 = 0.0; - state.dataHeatBalFanSys->ZoneW1 = state.dataEnvrn->OutHumRat; - state.dataHeatBalFanSys->ZoneWMX = state.dataEnvrn->OutHumRat; - state.dataHeatBalFanSys->ZoneWM2 = state.dataEnvrn->OutHumRat; state.dataHeatBalFanSys->PreviousMeasuredZT1 = 0.0; // Hybrid modeling state.dataHeatBalFanSys->PreviousMeasuredZT2 = 0.0; // Hybrid modeling state.dataHeatBalFanSys->PreviousMeasuredZT3 = 0.0; // Hybrid modeling @@ -3305,7 +3041,7 @@ void InitZoneAirSetPoints(EnergyPlusData &state) state.dataZoneTempPredictorCorrector->MyDayFlag = true; } - for (Loop = 1; Loop <= state.dataZoneCtrls->NumTempControlledZones; ++Loop) { + for (int Loop = 1; Loop <= state.dataZoneCtrls->NumTempControlledZones; ++Loop) { if (state.dataZoneEquip->ZoneEquipInputsFilled && !state.dataZoneTempPredictorCorrector->ControlledZonesChecked) { if (!VerifyControlledZoneForThermostat(state, TempControlledZone(Loop).ZoneName)) { ShowSevereError(state, @@ -3318,7 +3054,7 @@ void InitZoneAirSetPoints(EnergyPlusData &state) } if (TempControlledZone(Loop).ManageDemand) { - ZoneNum = TempControlledZone(Loop).ActualZoneNum; + int ZoneNum = TempControlledZone(Loop).ActualZoneNum; switch (TempControlType(ZoneNum)) { case DataHVACGlobals::ThermostatType::SingleHeating: @@ -3360,7 +3096,7 @@ void InitZoneAirSetPoints(EnergyPlusData &state) } } - for (Loop = 1; Loop <= state.dataZoneCtrls->NumComfortControlledZones; ++Loop) { + for (int Loop = 1; Loop <= state.dataZoneCtrls->NumComfortControlledZones; ++Loop) { if (state.dataZoneEquip->ZoneEquipInputsFilled && !state.dataZoneTempPredictorCorrector->ControlledZonesChecked) { if (!VerifyControlledZoneForThermostat(state, ComfortControlledZone(Loop).ZoneName)) { ShowSevereError(state, @@ -3372,7 +3108,7 @@ void InitZoneAirSetPoints(EnergyPlusData &state) } } if (ComfortControlledZone(Loop).ManageDemand) { - ZoneNum = ComfortControlledZone(Loop).ActualZoneNum; + int ZoneNum = ComfortControlledZone(Loop).ActualZoneNum; switch (state.dataHeatBalFanSys->ComfortControlType(ZoneNum)) { case DataHVACGlobals::ThermostatType::SingleHeating: @@ -3429,6 +3165,51 @@ void InitZoneAirSetPoints(EnergyPlusData &state) } } +void ZoneSpaceHeatBalanceData::beginEnvironmentInit(EnergyPlusData &state) +{ + for (int i = 0; i <= 3; ++i) { + this->ZTM[i] = 0.0; + this->WPrevZoneTS[i] = state.dataEnvrn->OutHumRat; + this->DSWPrevZoneTS[i] = state.dataEnvrn->OutHumRat; + this->WPrevZoneTSTemp[i] = 0.0; + } + this->WZoneTimeMinusP = state.dataEnvrn->OutHumRat; + this->ZoneW1 = state.dataEnvrn->OutHumRat; + this->ZoneWMX = state.dataEnvrn->OutHumRat; + this->ZoneWM2 = state.dataEnvrn->OutHumRat; + this->ZoneAirHumRatTemp = 0.0; + this->TempIndZnLd = 0.0; + this->TempDepZnLd = 0.0; + this->ZoneAirRelHum = 0.0; + this->AirPowerCap = 0.0; + this->ZoneT1 = 0.0; +} + +void ZoneSpaceHeatBalanceData::setUpOutputVars(EnergyPlusData &state, std::string_view prefix, std::string_view name) +{ + SetupOutputVariable(state, + format("{} Air Temperature", prefix), + OutputProcessor::Unit::C, + this->ZT, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + SetupOutputVariable(state, + format("{} Air Humidity Ratio", prefix), + OutputProcessor::Unit::None, + this->ZoneAirHumRat, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); + SetupOutputVariable(state, + format("{} Air Relative Humidity", prefix), + OutputProcessor::Unit::Perc, + this->ZoneAirRelHum, + OutputProcessor::SOVTimeStepType::System, + OutputProcessor::SOVStoreType::Average, + name); +} + void PredictSystemLoads(EnergyPlusData &state, bool const ShortenTimeStepSys, bool const UseZoneTimeStepHistory, // if true then use zone timestep history, if false use system time step @@ -3469,120 +3250,77 @@ void PredictSystemLoads(EnergyPlusData &state, // the type of system being simulated. // 3. Calculate zone energy requirements - using InternalHeatGains::SumAllInternalConvectionGainsExceptPeople; - using RoomAirModelAirflowNetwork::LoadPredictionRoomAirModelAirflowNetwork; - using ScheduleManager::GetCurrentScheduleValue; - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - Real64 SumIntGain; // Zone sum of convective internal gains - Real64 SumHA; // Zone sum of Hc*Area - Real64 SumHATsurf; // Zone sum of Hc*Area*Tsurf - Real64 SumHATref; // Zone sum of Hc*Area*Tref, for ceiling diffuser convection correlation - Real64 SumMCp; // Zone sum of MassFlowRate*Cp - Real64 SumMCpT; // Zone sum of MassFlowRate*Cp*T - Real64 SumSysMCp; // Zone sum of air system MassFlowRate*Cp - Real64 SumSysMCpT; // Zone sum of air system MassFlowRate*Cp* - Real64 SumIntGainExceptPeople; - Real64 TempDepCoef; // Formerly CoefSumha - Real64 TempIndCoef; // Formerly CoefSumhat - Real64 AirCap; // Formerly CoefAirrat - Real64 TempHistoryTerm; - int ZoneNum; - Real64 ZoneT; // Zone temperature at previous time step - int RelativeZoneNum; - int ActualZoneNum; - int I; - int Itemp; - Real64 SetpointOffset; - int RoomAirNode; - int LoopNode; - Real64 RAFNFrac; - - SumIntGainExceptPeople = 0.0; - - auto &Zone = state.dataHeatBal->Zone; - auto &TempControlledZone = state.dataZoneCtrls->TempControlledZone; - auto &TempZoneThermostatSetPoint = state.dataHeatBalFanSys->TempZoneThermostatSetPoint; - auto &TempControlType = state.dataHeatBalFanSys->TempControlType; - auto &ZoneThermostatSetPointLo = state.dataHeatBalFanSys->ZoneThermostatSetPointLo; - auto &ZoneThermostatSetPointHi = state.dataHeatBalFanSys->ZoneThermostatSetPointHi; - auto &RoomAirflowNetworkZoneInfo = state.dataRoomAirMod->RoomAirflowNetworkZoneInfo; - auto &StageControlledZone = state.dataZoneCtrls->StageControlledZone; - auto &TempDepZnLd = state.dataZoneTempPredictorCorrector->TempDepZnLd; - auto &TempIndZnLd = state.dataZoneTempPredictorCorrector->TempIndZnLd; - auto &ZoneSysEnergyDemand = state.dataZoneEnergyDemand->ZoneSysEnergyDemand; - auto &MAT = state.dataHeatBalFanSys->MAT; - auto &ZoneT1 = state.dataHeatBalFanSys->ZoneT1; - auto &Node = state.dataLoopNodes->Node; - auto &ZoneAirSolutionAlgo = state.dataHeatBal->ZoneAirSolutionAlgo; - auto &AIRRAT = state.dataHeatBalFanSys->AIRRAT; - // Staged thermostat setpoint if (state.dataZoneTempPredictorCorrector->NumStageCtrZone > 0) { - for (RelativeZoneNum = 1; RelativeZoneNum <= state.dataZoneTempPredictorCorrector->NumStageCtrZone; ++RelativeZoneNum) { - ActualZoneNum = StageControlledZone(RelativeZoneNum).ActualZoneNum; - ZoneT = MAT(ActualZoneNum); - if (ShortenTimeStepSys) ZoneT = state.dataHeatBalFanSys->XMPT(ActualZoneNum); - StageControlledZone(RelativeZoneNum).HeatSetPoint = GetCurrentScheduleValue(state, StageControlledZone(RelativeZoneNum).HSBchedIndex); - StageControlledZone(RelativeZoneNum).CoolSetPoint = GetCurrentScheduleValue(state, StageControlledZone(RelativeZoneNum).CSBchedIndex); - if (StageControlledZone(RelativeZoneNum).HeatSetPoint >= StageControlledZone(RelativeZoneNum).CoolSetPoint) { - ++StageControlledZone(RelativeZoneNum).StageErrCount; - if (StageControlledZone(RelativeZoneNum).StageErrCount < 2) { + 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 &thisZoneThermostatSetPointLo = state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ActualZoneNum); + auto &thisZoneThermostatSetPointHi = state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ActualZoneNum); + Real64 ZoneT = thisZoneHB.MAT; // Zone temperature at previous time step + if (ShortenTimeStepSys) ZoneT = thisZoneHB.XMPT; + thisStageControlZone.HeatSetPoint = ScheduleManager::GetCurrentScheduleValue(state, thisStageControlZone.HSBchedIndex); + thisStageControlZone.CoolSetPoint = ScheduleManager::GetCurrentScheduleValue(state, thisStageControlZone.CSBchedIndex); + if (thisStageControlZone.HeatSetPoint >= thisStageControlZone.CoolSetPoint) { + ++thisStageControlZone.StageErrCount; + if (thisStageControlZone.StageErrCount < 2) { ShowWarningError(state, "ZoneControl:Thermostat:StagedDualSetpoint: The heating setpoint is equal to or above the cooling setpoint in " + - StageControlledZone(RelativeZoneNum).Name); + thisStageControlZone.Name); ShowContinueError(state, "The zone heating setpoint is set to the cooling setpoint - 0.1C."); ShowContinueErrorTimeStamp(state, "Occurrence info:"); } else { ShowRecurringWarningErrorAtEnd(state, "The heating setpoint is still above the cooling setpoint", - StageControlledZone(RelativeZoneNum).StageErrIndex, - StageControlledZone(RelativeZoneNum).HeatSetPoint, - StageControlledZone(RelativeZoneNum).HeatSetPoint); + thisStageControlZone.StageErrIndex, + thisStageControlZone.HeatSetPoint, + thisStageControlZone.HeatSetPoint); } - StageControlledZone(RelativeZoneNum).HeatSetPoint = StageControlledZone(RelativeZoneNum).CoolSetPoint - 0.1; //??????????? + thisStageControlZone.HeatSetPoint = thisStageControlZone.CoolSetPoint - 0.1; //??????????? } // Determine either cooling or heating - if (StageControlledZone(RelativeZoneNum).CoolSetPoint < ZoneT) { // Cooling - SetpointOffset = ZoneT - StageControlledZone(RelativeZoneNum).CoolSetPoint; - Itemp = 0; - for (I = 1; I <= StageControlledZone(RelativeZoneNum).NumOfCoolStages; ++I) { - if (SetpointOffset >= StageControlledZone(RelativeZoneNum).CoolTOffset(I)) { + if (thisStageControlZone.CoolSetPoint < ZoneT) { // Cooling + Real64 SetpointOffset = ZoneT - thisStageControlZone.CoolSetPoint; + int Itemp = 0; + for (int I = 1; I <= thisStageControlZone.NumOfCoolStages; ++I) { + if (SetpointOffset >= thisStageControlZone.CoolTOffset(I)) { Itemp = -I; } } - ZoneSysEnergyDemand(ActualZoneNum).StageNum = Itemp; - if (SetpointOffset >= 0.5 * StageControlledZone(RelativeZoneNum).CoolThroRange) { - ZoneThermostatSetPointHi(ActualZoneNum) = - StageControlledZone(RelativeZoneNum).CoolSetPoint - 0.5 * StageControlledZone(RelativeZoneNum).CoolThroRange; + state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ActualZoneNum).StageNum = Itemp; + if (SetpointOffset >= 0.5 * thisStageControlZone.CoolThroRange) { + thisZoneThermostatSetPointHi = thisStageControlZone.CoolSetPoint - 0.5 * thisStageControlZone.CoolThroRange; } else { - ZoneThermostatSetPointHi(ActualZoneNum) = - StageControlledZone(RelativeZoneNum).CoolSetPoint + 0.5 * StageControlledZone(RelativeZoneNum).CoolThroRange; - } - ZoneThermostatSetPointLo(ActualZoneNum) = ZoneThermostatSetPointHi(ActualZoneNum); - } else if (StageControlledZone(RelativeZoneNum).HeatSetPoint > ZoneT) { // heating - SetpointOffset = ZoneT - StageControlledZone(RelativeZoneNum).HeatSetPoint; - Itemp = 0; - for (I = 1; I <= StageControlledZone(RelativeZoneNum).NumOfHeatStages; ++I) { - if (std::abs(SetpointOffset) >= std::abs(StageControlledZone(RelativeZoneNum).HeatTOffset(I))) { + thisZoneThermostatSetPointHi = thisStageControlZone.CoolSetPoint + 0.5 * thisStageControlZone.CoolThroRange; + } + thisZoneThermostatSetPointLo = thisZoneThermostatSetPointHi; + } else if (thisStageControlZone.HeatSetPoint > ZoneT) { // heating + Real64 SetpointOffset = ZoneT - thisStageControlZone.HeatSetPoint; + int Itemp = 0; + for (int I = 1; I <= thisStageControlZone.NumOfHeatStages; ++I) { + if (std::abs(SetpointOffset) >= std::abs(thisStageControlZone.HeatTOffset(I))) { Itemp = I; } } - ZoneSysEnergyDemand(ActualZoneNum).StageNum = Itemp; - if (std::abs(SetpointOffset) >= 0.5 * StageControlledZone(RelativeZoneNum).CoolThroRange) { - ZoneThermostatSetPointLo(ActualZoneNum) = - StageControlledZone(RelativeZoneNum).HeatSetPoint + 0.5 * StageControlledZone(RelativeZoneNum).HeatThroRange; + state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ActualZoneNum).StageNum = Itemp; + if (std::abs(SetpointOffset) >= 0.5 * thisStageControlZone.CoolThroRange) { + thisZoneThermostatSetPointLo = thisStageControlZone.HeatSetPoint + 0.5 * thisStageControlZone.HeatThroRange; } else { - ZoneThermostatSetPointLo(ActualZoneNum) = - StageControlledZone(RelativeZoneNum).HeatSetPoint - 0.5 * StageControlledZone(RelativeZoneNum).HeatThroRange; + thisZoneThermostatSetPointLo = thisStageControlZone.HeatSetPoint - 0.5 * thisStageControlZone.HeatThroRange; } - ZoneThermostatSetPointHi(ActualZoneNum) = ZoneThermostatSetPointLo(ActualZoneNum); + thisZoneThermostatSetPointHi = thisZoneThermostatSetPointLo; } else { - ZoneThermostatSetPointHi(ActualZoneNum) = - StageControlledZone(RelativeZoneNum).CoolSetPoint + 0.5 * StageControlledZone(RelativeZoneNum).CoolThroRange; - ZoneThermostatSetPointLo(ActualZoneNum) = - StageControlledZone(RelativeZoneNum).HeatSetPoint - 0.5 * StageControlledZone(RelativeZoneNum).HeatThroRange; - ZoneSysEnergyDemand(ActualZoneNum).StageNum = 0; + thisZoneThermostatSetPointHi = thisStageControlZone.CoolSetPoint + 0.5 * thisStageControlZone.CoolThroRange; + thisZoneThermostatSetPointLo = thisStageControlZone.HeatSetPoint - 0.5 * thisStageControlZone.HeatThroRange; + state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ActualZoneNum).StageNum = 0; + } + // SpaceHB TODO: For now, set space stagenum to zone stagenum - later need to see what space the thermostat is in + if (state.dataHeatBal->doSpaceHeatBalance) { + for (int spaceNum : state.dataHeatBal->Zone(ActualZoneNum).spaceIndexes) { + state.dataZoneEnergyDemand->spaceSysEnergyDemand(spaceNum).StageNum = + state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ActualZoneNum).StageNum; + } } } } @@ -3591,113 +3329,105 @@ void PredictSystemLoads(EnergyPlusData &state, if (state.dataZoneTempPredictorCorrector->NumOnOffCtrZone > 0) { Real64 TempTole = 0.02; Real64 Tprev; - for (RelativeZoneNum = 1; RelativeZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++RelativeZoneNum) { - if (TempControlledZone(RelativeZoneNum).DeltaTCutSet > 0.0) { + for (int RelativeZoneNum = 1; RelativeZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++RelativeZoneNum) { + auto &thisTempControlledZone = state.dataZoneCtrls->TempControlledZone(RelativeZoneNum); + if (thisTempControlledZone.DeltaTCutSet > 0.0) { if (ShortenTimeStepSys) { - TempControlledZone(RelativeZoneNum).HeatModeLast = TempControlledZone(RelativeZoneNum).HeatModeLastSave; - TempControlledZone(RelativeZoneNum).CoolModeLast = TempControlledZone(RelativeZoneNum).CoolModeLastSave; + thisTempControlledZone.HeatModeLast = thisTempControlledZone.HeatModeLastSave; + thisTempControlledZone.CoolModeLast = thisTempControlledZone.CoolModeLastSave; } else { - TempControlledZone(RelativeZoneNum).HeatModeLastSave = TempControlledZone(RelativeZoneNum).HeatModeLast; - TempControlledZone(RelativeZoneNum).CoolModeLastSave = TempControlledZone(RelativeZoneNum).CoolModeLast; + thisTempControlledZone.HeatModeLastSave = thisTempControlledZone.HeatModeLast; + thisTempControlledZone.CoolModeLastSave = thisTempControlledZone.CoolModeLast; } - ZoneNum = TempControlledZone(RelativeZoneNum).ActualZoneNum; - - TempControlledZone(RelativeZoneNum).CoolOffFlag = false; - TempControlledZone(RelativeZoneNum).HeatOffFlag = false; - if (ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::ThirdOrder) { - Tprev = MAT(ZoneNum); - if (ShortenTimeStepSys) Tprev = state.dataHeatBalFanSys->XMPT(ZoneNum); + auto &thisTempZoneThermostatSetPoint = state.dataHeatBalFanSys->TempZoneThermostatSetPoint(thisTempControlledZone.ActualZoneNum); + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(thisTempControlledZone.ActualZoneNum); + auto &thisZoneThermostatSetPointLo = state.dataHeatBalFanSys->ZoneThermostatSetPointLo(thisTempControlledZone.ActualZoneNum); + auto &thisZoneThermostatSetPointHi = state.dataHeatBalFanSys->ZoneThermostatSetPointHi(thisTempControlledZone.ActualZoneNum); + + thisTempControlledZone.CoolOffFlag = false; + thisTempControlledZone.HeatOffFlag = false; + if (state.dataHeatBal->ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::ThirdOrder) { + Tprev = thisZoneHB.MAT; + if (ShortenTimeStepSys) Tprev = thisZoneHB.XMPT; } else { - Tprev = ZoneT1(ZoneNum); + Tprev = thisZoneHB.ZoneT1; } - switch (TempControlType(ZoneNum)) { + switch (state.dataHeatBalFanSys->TempControlType(thisTempControlledZone.ActualZoneNum)) { case DataHVACGlobals::ThermostatType::SingleHeating: - TempZoneThermostatSetPoint(ZoneNum) = TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointLo; - ZoneThermostatSetPointLo(ZoneNum) = TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointLo; - if (Tprev < TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointLo + TempTole) { - TempZoneThermostatSetPoint(ZoneNum) = - TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointLo + TempControlledZone(RelativeZoneNum).DeltaTCutSet; - ZoneThermostatSetPointLo(ZoneNum) = TempZoneThermostatSetPoint(ZoneNum); - } else if (Tprev > TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointLo && - (Tprev < TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointLo + - TempControlledZone(RelativeZoneNum).DeltaTCutSet - TempTole)) { - TempZoneThermostatSetPoint(ZoneNum) = - TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointLo + TempControlledZone(RelativeZoneNum).DeltaTCutSet; - ZoneThermostatSetPointLo(ZoneNum) = TempZoneThermostatSetPoint(ZoneNum); + thisTempZoneThermostatSetPoint = thisTempControlledZone.ZoneThermostatSetPointLo; + thisZoneThermostatSetPointLo = thisTempControlledZone.ZoneThermostatSetPointLo; + if (Tprev < thisTempControlledZone.ZoneThermostatSetPointLo + TempTole) { + thisTempZoneThermostatSetPoint = thisTempControlledZone.ZoneThermostatSetPointLo + thisTempControlledZone.DeltaTCutSet; + thisZoneThermostatSetPointLo = thisTempZoneThermostatSetPoint; + } else if (Tprev > thisTempControlledZone.ZoneThermostatSetPointLo && + (Tprev < thisTempControlledZone.ZoneThermostatSetPointLo + thisTempControlledZone.DeltaTCutSet - TempTole)) { + thisTempZoneThermostatSetPoint = thisTempControlledZone.ZoneThermostatSetPointLo + thisTempControlledZone.DeltaTCutSet; + thisZoneThermostatSetPointLo = thisTempZoneThermostatSetPoint; } else { - TempControlledZone(RelativeZoneNum).HeatOffFlag = true; + thisTempControlledZone.HeatOffFlag = true; } - if (TempControlledZone(RelativeZoneNum).HeatModeLast && Tprev > TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointLo) { - TempZoneThermostatSetPoint(ZoneNum) = TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointLo; - ZoneThermostatSetPointLo(ZoneNum) = TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointLo; - TempControlledZone(RelativeZoneNum).HeatOffFlag = true; + if (thisTempControlledZone.HeatModeLast && Tprev > thisTempControlledZone.ZoneThermostatSetPointLo) { + thisTempZoneThermostatSetPoint = thisTempControlledZone.ZoneThermostatSetPointLo; + thisZoneThermostatSetPointLo = thisTempControlledZone.ZoneThermostatSetPointLo; + thisTempControlledZone.HeatOffFlag = true; } break; case DataHVACGlobals::ThermostatType::SingleCooling: - TempZoneThermostatSetPoint(ZoneNum) = TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointHi; - ZoneThermostatSetPointHi(ZoneNum) = TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointHi; - if (Tprev > TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointHi - TempTole) { - TempZoneThermostatSetPoint(ZoneNum) = - TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointHi - TempControlledZone(RelativeZoneNum).DeltaTCutSet; - ZoneThermostatSetPointHi(ZoneNum) = TempZoneThermostatSetPoint(ZoneNum); - } else if (Tprev < TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointHi && - Tprev > TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointHi - - TempControlledZone(RelativeZoneNum).DeltaTCutSet + TempTole) { - TempZoneThermostatSetPoint(ZoneNum) = - TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointHi - TempControlledZone(RelativeZoneNum).DeltaTCutSet; - ZoneThermostatSetPointHi(ZoneNum) = TempZoneThermostatSetPoint(ZoneNum); + thisTempZoneThermostatSetPoint = thisTempControlledZone.ZoneThermostatSetPointHi; + thisZoneThermostatSetPointHi = thisTempControlledZone.ZoneThermostatSetPointHi; + if (Tprev > thisTempControlledZone.ZoneThermostatSetPointHi - TempTole) { + thisTempZoneThermostatSetPoint = thisTempControlledZone.ZoneThermostatSetPointHi - thisTempControlledZone.DeltaTCutSet; + thisZoneThermostatSetPointHi = thisTempZoneThermostatSetPoint; + } else if (Tprev < thisTempControlledZone.ZoneThermostatSetPointHi && + Tprev > thisTempControlledZone.ZoneThermostatSetPointHi - thisTempControlledZone.DeltaTCutSet + TempTole) { + thisTempZoneThermostatSetPoint = thisTempControlledZone.ZoneThermostatSetPointHi - thisTempControlledZone.DeltaTCutSet; + thisZoneThermostatSetPointHi = thisTempZoneThermostatSetPoint; } else { - TempControlledZone(RelativeZoneNum).CoolOffFlag = true; + thisTempControlledZone.CoolOffFlag = true; } - if (TempControlledZone(RelativeZoneNum).CoolModeLast && Tprev < TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointHi) { - TempZoneThermostatSetPoint(ZoneNum) = TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointHi; - ZoneThermostatSetPointHi(ZoneNum) = TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointHi; - TempControlledZone(RelativeZoneNum).CoolOffFlag = true; + if (thisTempControlledZone.CoolModeLast && Tprev < thisTempControlledZone.ZoneThermostatSetPointHi) { + thisTempZoneThermostatSetPoint = thisTempControlledZone.ZoneThermostatSetPointHi; + thisZoneThermostatSetPointHi = thisTempControlledZone.ZoneThermostatSetPointHi; + thisTempControlledZone.CoolOffFlag = true; } break; case DataHVACGlobals::ThermostatType::DualSetPointWithDeadBand: - ZoneThermostatSetPointHi(ZoneNum) = TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointHi; - ZoneThermostatSetPointLo(ZoneNum) = TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointLo; - if (Tprev > TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointHi - TempTole) { - ZoneThermostatSetPointHi(ZoneNum) = - TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointHi - TempControlledZone(RelativeZoneNum).DeltaTCutSet; - } else if (Tprev < TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointHi && - Tprev > TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointHi - - TempControlledZone(RelativeZoneNum).DeltaTCutSet + TempTole) { - ZoneThermostatSetPointHi(ZoneNum) = - TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointHi - TempControlledZone(RelativeZoneNum).DeltaTCutSet; + thisZoneThermostatSetPointHi = thisTempControlledZone.ZoneThermostatSetPointHi; + thisZoneThermostatSetPointLo = thisTempControlledZone.ZoneThermostatSetPointLo; + if (Tprev > thisTempControlledZone.ZoneThermostatSetPointHi - TempTole) { + thisZoneThermostatSetPointHi = thisTempControlledZone.ZoneThermostatSetPointHi - thisTempControlledZone.DeltaTCutSet; + } else if (Tprev < thisTempControlledZone.ZoneThermostatSetPointHi && + Tprev > thisTempControlledZone.ZoneThermostatSetPointHi - thisTempControlledZone.DeltaTCutSet + TempTole) { + thisZoneThermostatSetPointHi = thisTempControlledZone.ZoneThermostatSetPointHi - thisTempControlledZone.DeltaTCutSet; } else { - TempControlledZone(RelativeZoneNum).CoolOffFlag = true; + thisTempControlledZone.CoolOffFlag = true; } - if (TempControlledZone(RelativeZoneNum).CoolModeLast && Tprev < TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointHi) { - ZoneThermostatSetPointHi(ZoneNum) = TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointHi; - TempControlledZone(RelativeZoneNum).CoolOffFlag = true; + if (thisTempControlledZone.CoolModeLast && Tprev < thisTempControlledZone.ZoneThermostatSetPointHi) { + thisZoneThermostatSetPointHi = thisTempControlledZone.ZoneThermostatSetPointHi; + thisTempControlledZone.CoolOffFlag = true; } - if (Tprev < TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointLo + TempTole) { - ZoneThermostatSetPointLo(ZoneNum) = - TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointLo + TempControlledZone(RelativeZoneNum).DeltaTCutSet; - } else if (Tprev > TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointLo && - (Tprev < TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointLo + - TempControlledZone(RelativeZoneNum).DeltaTCutSet - TempTole)) { - ZoneThermostatSetPointLo(ZoneNum) = - TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointLo + TempControlledZone(RelativeZoneNum).DeltaTCutSet; + if (Tprev < thisTempControlledZone.ZoneThermostatSetPointLo + TempTole) { + thisZoneThermostatSetPointLo = thisTempControlledZone.ZoneThermostatSetPointLo + thisTempControlledZone.DeltaTCutSet; + } else if (Tprev > thisTempControlledZone.ZoneThermostatSetPointLo && + (Tprev < thisTempControlledZone.ZoneThermostatSetPointLo + thisTempControlledZone.DeltaTCutSet - TempTole)) { + thisZoneThermostatSetPointLo = thisTempControlledZone.ZoneThermostatSetPointLo + thisTempControlledZone.DeltaTCutSet; } else { - TempControlledZone(RelativeZoneNum).HeatOffFlag = true; + thisTempControlledZone.HeatOffFlag = true; } - if (TempControlledZone(RelativeZoneNum).HeatModeLast && Tprev > TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointLo) { - ZoneThermostatSetPointLo(ZoneNum) = TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointLo; - TempControlledZone(RelativeZoneNum).HeatOffFlag = true; + if (thisTempControlledZone.HeatModeLast && Tprev > thisTempControlledZone.ZoneThermostatSetPointLo) { + thisZoneThermostatSetPointLo = thisTempControlledZone.ZoneThermostatSetPointLo; + thisTempControlledZone.HeatOffFlag = true; } // check setpoint for both and provde an error message - if (ZoneThermostatSetPointLo(ZoneNum) >= ZoneThermostatSetPointHi(ZoneNum)) { + if (thisZoneThermostatSetPointLo >= thisZoneThermostatSetPointHi) { ShowSevereError(state, "DualSetPointWithDeadBand: When Temperature Difference Between Cutout And Setpoint is applied, the heating " "setpoint is greater than the cooling setpoint. "); - ShowContinueErrorTimeStamp(state, "occurs in Zone=" + Zone(ZoneNum).Name); - ShowContinueError(state, format("Zone Heating ThermostatSetPoint={:.2R}", ZoneThermostatSetPointLo(ZoneNum))); - ShowContinueError(state, format("Zone Cooling ThermostatSetPoint={:.2R}", ZoneThermostatSetPointHi(ZoneNum))); + ShowContinueErrorTimeStamp(state, "occurs in Zone=" + state.dataHeatBal->Zone(thisTempControlledZone.ActualZoneNum).Name); + ShowContinueError(state, format("Zone Heating ThermostatSetPoint={:.2R}", thisZoneThermostatSetPointLo)); + ShowContinueError(state, format("Zone Cooling ThermostatSetPoint={:.2R}", thisZoneThermostatSetPointHi)); ShowFatalError(state, "Program terminates due to above conditions."); } break; @@ -3708,267 +3438,146 @@ void PredictSystemLoads(EnergyPlusData &state, } } - auto &TimeStepSys(state.dataHVACGlobal->TimeStepSys); - - // Update zone temperatures - for (ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { - - if (ShortenTimeStepSys) { - // timestep has just shifted from full zone timestep to a new shorter system timestep - // throw away last updates in corrector and rewind for resimulating smaller timestep - if (Zone(ZoneNum).SystemZoneNodeNumber > 0) { // roll back result for zone air node, - Node(Zone(ZoneNum).SystemZoneNodeNumber).Temp = state.dataHeatBalFanSys->XMAT(ZoneNum); - state.dataHeatBalFanSys->TempTstatAir(ZoneNum) = state.dataHeatBalFanSys->XMAT(ZoneNum); - Node(Zone(ZoneNum).SystemZoneNodeNumber).HumRat = state.dataHeatBalFanSys->WZoneTimeMinus1(ZoneNum); - Node(Zone(ZoneNum).SystemZoneNodeNumber).Enthalpy = - PsyHFnTdbW(state.dataHeatBalFanSys->XMAT(ZoneNum), state.dataHeatBalFanSys->WZoneTimeMinus1(ZoneNum)); - } - - if (state.dataHVACGlobal->NumOfSysTimeSteps != - state.dataHVACGlobal->NumOfSysTimeStepsLastZoneTimeStep) { // cannot reuse existing DS data, interpolate from zone time - - // MAT(ZoneNum), state.dataHeatBalFanSys->XMAT(ZoneNum), state.dataHeatBalFanSys->XM2T(ZoneNum), - // state.dataHeatBalFanSys->XM3T(ZoneNum), state.dataHeatBalFanSys->XM4T(ZoneNum), & - DownInterpolate4HistoryValues(PriorTimeStep, - TimeStepSys, - state.dataHeatBalFanSys->XMAT(ZoneNum), - state.dataHeatBalFanSys->XM2T(ZoneNum), - state.dataHeatBalFanSys->XM3T(ZoneNum), - MAT(ZoneNum), - state.dataHeatBalFanSys->DSXMAT(ZoneNum), - state.dataHeatBalFanSys->DSXM2T(ZoneNum), - state.dataHeatBalFanSys->DSXM3T(ZoneNum), - state.dataHeatBalFanSys->DSXM4T(ZoneNum)); - // ZoneAirHumRat(ZoneNum), WZoneTimeMinus1(ZoneNum), WZoneTimeMinus2(ZoneNum), & - // WZoneTimeMinus3(ZoneNum), WZoneTimeMinus4(ZoneNum), & - DownInterpolate4HistoryValues(PriorTimeStep, - TimeStepSys, - state.dataHeatBalFanSys->WZoneTimeMinus1(ZoneNum), - state.dataHeatBalFanSys->WZoneTimeMinus2(ZoneNum), - state.dataHeatBalFanSys->WZoneTimeMinus3(ZoneNum), - state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum), - state.dataHeatBalFanSys->DSWZoneTimeMinus1(ZoneNum), - state.dataHeatBalFanSys->DSWZoneTimeMinus2(ZoneNum), - state.dataHeatBalFanSys->DSWZoneTimeMinus3(ZoneNum), - state.dataHeatBalFanSys->DSWZoneTimeMinus4(ZoneNum)); - - if (state.dataRoomAirMod->IsZoneDV(ZoneNum) || state.dataRoomAirMod->IsZoneUI(ZoneNum)) { - - // MATFloor(ZoneNum), XMATFloor(ZoneNum), XM2TFloor(ZoneNum), & - // XM3TFloor(ZoneNum), XM4TFloor(ZoneNum) , & - DownInterpolate4HistoryValues(PriorTimeStep, - TimeStepSys, - state.dataRoomAirMod->XMATFloor(ZoneNum), - state.dataRoomAirMod->XM2TFloor(ZoneNum), - state.dataRoomAirMod->XM3TFloor(ZoneNum), - state.dataRoomAirMod->MATFloor(ZoneNum), - state.dataRoomAirMod->DSXMATFloor(ZoneNum), - state.dataRoomAirMod->DSXM2TFloor(ZoneNum), - state.dataRoomAirMod->DSXM3TFloor(ZoneNum), - state.dataRoomAirMod->DSXM4TFloor(ZoneNum)); - DownInterpolate4HistoryValues(PriorTimeStep, - TimeStepSys, - state.dataRoomAirMod->XMATOC(ZoneNum), - state.dataRoomAirMod->XM2TOC(ZoneNum), - state.dataRoomAirMod->XM3TOC(ZoneNum), - state.dataRoomAirMod->MATOC(ZoneNum), - state.dataRoomAirMod->DSXMATOC(ZoneNum), - state.dataRoomAirMod->DSXM2TOC(ZoneNum), - state.dataRoomAirMod->DSXM3TOC(ZoneNum), - state.dataRoomAirMod->DSXM4TOC(ZoneNum)); - // MATMX(ZoneNum), XMATMX(ZoneNum), XM2TMX(ZoneNum), & - // XM3TMX(ZoneNum), XM4TMX(ZoneNum) , & - DownInterpolate4HistoryValues(PriorTimeStep, - TimeStepSys, - state.dataRoomAirMod->XMATMX(ZoneNum), - state.dataRoomAirMod->XM2TMX(ZoneNum), - state.dataRoomAirMod->XM3TMX(ZoneNum), - state.dataRoomAirMod->MATMX(ZoneNum), - state.dataRoomAirMod->DSXMATMX(ZoneNum), - state.dataRoomAirMod->DSXM2TMX(ZoneNum), - state.dataRoomAirMod->DSXM3TMX(ZoneNum), - state.dataRoomAirMod->DSXM4TMX(ZoneNum)); - } - if (state.dataRoomAirMod->AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { - for (LoopNode = 1; LoopNode <= RoomAirflowNetworkZoneInfo(ZoneNum).NumOfAirNodes; ++LoopNode) { - auto &ThisRAFNNode(RoomAirflowNetworkZoneInfo(ZoneNum).Node(LoopNode)); - DownInterpolate4HistoryValues(PriorTimeStep, - TimeStepSys, - ThisRAFNNode.AirTempX1, - ThisRAFNNode.AirTempX2, - ThisRAFNNode.AirTempX3, - ThisRAFNNode.AirTemp, - ThisRAFNNode.AirTempDSX1, - ThisRAFNNode.AirTempDSX2, - ThisRAFNNode.AirTempDSX3, - ThisRAFNNode.AirTempDSX4); - DownInterpolate4HistoryValues(PriorTimeStep, - TimeStepSys, - ThisRAFNNode.HumRatX1, - ThisRAFNNode.HumRatX2, - ThisRAFNNode.HumRatX3, - ThisRAFNNode.HumRat, - ThisRAFNNode.HumRatDSX1, - ThisRAFNNode.HumRatDSX2, - ThisRAFNNode.HumRatDSX3, - ThisRAFNNode.HumRatDSX4); - } - } - } else { // reuse history data in DS terms from last zone time step to preserve information that would be lost - // do nothing because DS history would have been pushed prior and should be ready - } - } - // now update the variables actually used in the balance equations. - if (UseZoneTimeStepHistory) { - state.dataHeatBalFanSys->ZTM1(ZoneNum) = state.dataHeatBalFanSys->XMAT(ZoneNum); - state.dataHeatBalFanSys->ZTM2(ZoneNum) = state.dataHeatBalFanSys->XM2T(ZoneNum); - state.dataHeatBalFanSys->ZTM3(ZoneNum) = state.dataHeatBalFanSys->XM3T(ZoneNum); - - state.dataHeatBalFanSys->WZoneTimeMinus1Temp(ZoneNum) = state.dataHeatBalFanSys->WZoneTimeMinus1(ZoneNum); - state.dataHeatBalFanSys->WZoneTimeMinus2Temp(ZoneNum) = state.dataHeatBalFanSys->WZoneTimeMinus2(ZoneNum); - state.dataHeatBalFanSys->WZoneTimeMinus3Temp(ZoneNum) = state.dataHeatBalFanSys->WZoneTimeMinus3(ZoneNum); - - } else { // use down-stepped history - state.dataHeatBalFanSys->ZTM1(ZoneNum) = state.dataHeatBalFanSys->DSXMAT(ZoneNum); - state.dataHeatBalFanSys->ZTM2(ZoneNum) = state.dataHeatBalFanSys->DSXM2T(ZoneNum); - state.dataHeatBalFanSys->ZTM3(ZoneNum) = state.dataHeatBalFanSys->DSXM3T(ZoneNum); - - state.dataHeatBalFanSys->WZoneTimeMinus1Temp(ZoneNum) = state.dataHeatBalFanSys->DSWZoneTimeMinus1(ZoneNum); - state.dataHeatBalFanSys->WZoneTimeMinus2Temp(ZoneNum) = state.dataHeatBalFanSys->DSWZoneTimeMinus2(ZoneNum); - state.dataHeatBalFanSys->WZoneTimeMinus3Temp(ZoneNum) = state.dataHeatBalFanSys->DSWZoneTimeMinus3(ZoneNum); - } - - AIRRAT(ZoneNum) = Zone(ZoneNum).Volume * Zone(ZoneNum).ZoneVolCapMultpSens * - PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, MAT(ZoneNum), state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)) * - PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)) / (TimeStepSys * DataGlobalConstants::SecInHour); - AirCap = AIRRAT(ZoneNum); - RAFNFrac = 0.0; - - // Calculate the various heat balance sums - - // NOTE: SumSysMCp and SumSysMCpT are not used in the predict step - CalcZoneSums(state, ZoneNum, SumIntGain, SumHA, SumHATsurf, SumHATref, SumMCp, SumMCpT, SumSysMCp, SumSysMCpT, false); - - // Sum all convective internal gains except for people: SumIntGainExceptPeople - if (state.dataHybridModel->FlagHybridModel_PC) { - SumIntGainExceptPeople = SumAllInternalConvectionGainsExceptPeople(state, ZoneNum); - } - - TempDepCoef = SumHA + SumMCp; - TempIndCoef = SumIntGain + SumHATsurf - SumHATref + SumMCpT + state.dataHeatBalFanSys->SysDepZoneLoadsLagged(ZoneNum); - if (state.dataRoomAirMod->AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::Mixing) { - TempHistoryTerm = AirCap * (3.0 * state.dataHeatBalFanSys->ZTM1(ZoneNum) - (3.0 / 2.0) * state.dataHeatBalFanSys->ZTM2(ZoneNum) + - (1.0 / 3.0) * state.dataHeatBalFanSys->ZTM3(ZoneNum)); - TempDepZnLd(ZoneNum) = (11.0 / 6.0) * AirCap + TempDepCoef; - TempIndZnLd(ZoneNum) = TempHistoryTerm + TempIndCoef; - } else if (state.dataRoomAirMod->IsZoneDV(ZoneNum)) { - // UCSD displacement ventilation model - make dynamic term independent of TimeStepSys - TempHistoryTerm = AirCap * (3.0 * state.dataHeatBalFanSys->ZTM1(ZoneNum) - (3.0 / 2.0) * state.dataHeatBalFanSys->ZTM2(ZoneNum) + - (1.0 / 3.0) * state.dataHeatBalFanSys->ZTM3(ZoneNum)); - TempDepZnLd(ZoneNum) = (11.0 / 6.0) * AirCap + TempDepCoef; - TempIndZnLd(ZoneNum) = TempHistoryTerm + TempIndCoef; - } else if (state.dataRoomAirMod->IsZoneUI(ZoneNum)) { - // UCSD UFAD model - make dynamic term independent of TimeStepSys - TempHistoryTerm = AirCap * (3.0 * state.dataHeatBalFanSys->ZTM1(ZoneNum) - (3.0 / 2.0) * state.dataHeatBalFanSys->ZTM2(ZoneNum) + - (1.0 / 3.0) * state.dataHeatBalFanSys->ZTM3(ZoneNum)); - TempDepZnLd(ZoneNum) = (11.0 / 6.0) * AirCap + TempDepCoef; - TempIndZnLd(ZoneNum) = TempHistoryTerm + TempIndCoef; - } else if (state.dataRoomAirMod->AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { - // RoomAirflowNetworkModel - make dynamic term independent of TimeStepSys - if (RoomAirflowNetworkZoneInfo(ZoneNum).IsUsed) { - RoomAirNode = RoomAirflowNetworkZoneInfo(ZoneNum).ControlAirNodeID; - LoadPredictionRoomAirModelAirflowNetwork(state, ZoneNum, RoomAirNode); - TempDepCoef = - RoomAirflowNetworkZoneInfo(ZoneNum).Node(RoomAirNode).SumHA + RoomAirflowNetworkZoneInfo(ZoneNum).Node(RoomAirNode).SumLinkMCp; - TempIndCoef = RoomAirflowNetworkZoneInfo(ZoneNum).Node(RoomAirNode).SumIntSensibleGain + - RoomAirflowNetworkZoneInfo(ZoneNum).Node(RoomAirNode).SumHATsurf - - RoomAirflowNetworkZoneInfo(ZoneNum).Node(RoomAirNode).SumHATref + - RoomAirflowNetworkZoneInfo(ZoneNum).Node(RoomAirNode).SumLinkMCpT + - RoomAirflowNetworkZoneInfo(ZoneNum).Node(RoomAirNode).SysDepZoneLoadsLagged; - AirCap = RoomAirflowNetworkZoneInfo(ZoneNum).Node(RoomAirNode).AirVolume * Zone(ZoneNum).ZoneVolCapMultpSens * - RoomAirflowNetworkZoneInfo(ZoneNum).Node(RoomAirNode).RhoAir * RoomAirflowNetworkZoneInfo(ZoneNum).Node(RoomAirNode).CpAir / - (TimeStepSys * DataGlobalConstants::SecInHour); - AIRRAT(ZoneNum) = AirCap; - TempHistoryTerm = AirCap * (3.0 * state.dataHeatBalFanSys->ZTM1(ZoneNum) - (3.0 / 2.0) * state.dataHeatBalFanSys->ZTM2(ZoneNum) + - (1.0 / 3.0) * state.dataHeatBalFanSys->ZTM3(ZoneNum)); - TempDepZnLd(ZoneNum) = (11.0 / 6.0) * AirCap + TempDepCoef; - TempIndZnLd(ZoneNum) = TempHistoryTerm + TempIndCoef; - if (RoomAirflowNetworkZoneInfo(ZoneNum).Node(RoomAirNode).HasHVACAssigned) - RAFNFrac = RoomAirflowNetworkZoneInfo(ZoneNum).Node(RoomAirNode).HVAC(1).SupplyFraction; - } - } else { // other imperfectly mixed room models - TempHistoryTerm = AirCap * (3.0 * state.dataHeatBalFanSys->ZTM1(ZoneNum) - (3.0 / 2.0) * state.dataHeatBalFanSys->ZTM2(ZoneNum) + - (1.0 / 3.0) * state.dataHeatBalFanSys->ZTM3(ZoneNum)); - TempDepZnLd(ZoneNum) = (11.0 / 6.0) * AirCap + TempDepCoef; - TempIndZnLd(ZoneNum) = TempHistoryTerm + TempIndCoef; - } - - // Exact solution or Euler method - state.dataHVACGlobal->ShortenTimeStepSysRoomAir = false; - if (ZoneAirSolutionAlgo != DataHeatBalance::SolutionAlgo::ThirdOrder) { - if (ShortenTimeStepSys && TimeStepSys < state.dataGlobal->TimeStepZone) { - if (state.dataHVACGlobal->PreviousTimeStep < state.dataGlobal->TimeStepZone) { - ZoneT1(ZoneNum) = state.dataHeatBalFanSys->ZoneTM2(ZoneNum); - state.dataHeatBalFanSys->ZoneW1(ZoneNum) = state.dataHeatBalFanSys->ZoneWM2(ZoneNum); - if (state.dataRoomAirMod->AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { - for (LoopNode = 1; LoopNode <= RoomAirflowNetworkZoneInfo(ZoneNum).NumOfAirNodes; ++LoopNode) { - RoomAirflowNetworkZoneInfo(ZoneNum).Node(LoopNode).AirTempT1 = - RoomAirflowNetworkZoneInfo(ZoneNum).Node(LoopNode).AirTempTM2; - RoomAirflowNetworkZoneInfo(ZoneNum).Node(LoopNode).HumRatW1 = - RoomAirflowNetworkZoneInfo(ZoneNum).Node(LoopNode).HumRatWM2; - } - } + for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { + state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum).predictSystemLoad( + state, ShortenTimeStepSys, UseZoneTimeStepHistory, PriorTimeStep, zoneNum); + if (state.dataHeatBal->doSpaceHeatBalance) { + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).predictSystemLoad( + state, ShortenTimeStepSys, UseZoneTimeStepHistory, PriorTimeStep, zoneNum, spaceNum); + } + } + } + if (state.dataZoneTempPredictorCorrector->NumOnOffCtrZone > 0) { + for (int RelativeZoneNum = 1; RelativeZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++RelativeZoneNum) { + auto &thisTempControlledZone = state.dataZoneCtrls->TempControlledZone(RelativeZoneNum); + if (thisTempControlledZone.DeltaTCutSet > 0.0) { + int ZoneNum = thisTempControlledZone.ActualZoneNum; + if (thisTempControlledZone.CoolOffFlag && state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).TotalOutputRequired >= 0.0) { + thisTempControlledZone.CoolModeLast = true; } else { - ZoneT1(ZoneNum) = state.dataHeatBalFanSys->ZoneTMX(ZoneNum); - state.dataHeatBalFanSys->ZoneW1(ZoneNum) = state.dataHeatBalFanSys->ZoneWMX(ZoneNum); - if (state.dataRoomAirMod->AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { - for (LoopNode = 1; LoopNode <= RoomAirflowNetworkZoneInfo(ZoneNum).NumOfAirNodes; ++LoopNode) { - RoomAirflowNetworkZoneInfo(ZoneNum).Node(LoopNode).AirTempT1 = - RoomAirflowNetworkZoneInfo(ZoneNum).Node(LoopNode).AirTempTMX; - RoomAirflowNetworkZoneInfo(ZoneNum).Node(LoopNode).HumRatW1 = - RoomAirflowNetworkZoneInfo(ZoneNum).Node(LoopNode).HumRatWMX; - } - } + thisTempControlledZone.CoolModeLast = false; } - state.dataHVACGlobal->ShortenTimeStepSysRoomAir = true; - } else { - ZoneT1(ZoneNum) = state.dataHeatBalFanSys->ZT(ZoneNum); - state.dataHeatBalFanSys->ZoneW1(ZoneNum) = state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum); - if (state.dataRoomAirMod->AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { - for (LoopNode = 1; LoopNode <= RoomAirflowNetworkZoneInfo(ZoneNum).NumOfAirNodes; ++LoopNode) { - RoomAirflowNetworkZoneInfo(ZoneNum).Node(LoopNode).AirTempT1 = RoomAirflowNetworkZoneInfo(ZoneNum).Node(LoopNode).AirTemp; - RoomAirflowNetworkZoneInfo(ZoneNum).Node(LoopNode).HumRatW1 = RoomAirflowNetworkZoneInfo(ZoneNum).Node(LoopNode).HumRat; - } + if (thisTempControlledZone.HeatOffFlag && state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).TotalOutputRequired <= 0.0) { + thisTempControlledZone.HeatModeLast = true; + } else { + thisTempControlledZone.HeatModeLast = false; } } - TempDepZnLd(ZoneNum) = TempDepCoef; - TempIndZnLd(ZoneNum) = TempIndCoef; } + } +} +void ZoneSpaceHeatBalanceData::predictSystemLoad( + EnergyPlusData &state, + bool const shortenTimeStepSys, + bool const useZoneTimeStepHistory, // if true then use zone timestep history, if false use system time step + Real64 const priorTimeStep, // the old value for timestep length is passed for possible use in interpolating + int zoneNum, + int spaceNum) +{ + assert(zoneNum > 0); + this->updateTemperatures(state, shortenTimeStepSys, useZoneTimeStepHistory, priorTimeStep, zoneNum, spaceNum); + + Real64 volume = 0.0; + if (spaceNum > 0) { + volume = state.dataHeatBal->space(spaceNum).Volume; + } else { + volume = state.dataHeatBal->Zone(zoneNum).Volume; + } + this->AirPowerCap = volume * state.dataHeatBal->Zone(zoneNum).ZoneVolCapMultpSens * + Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, this->MAT, this->ZoneAirHumRat) * + Psychrometrics::PsyCpAirFnW(this->ZoneAirHumRat) / (state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour); + Real64 RAFNFrac = 0.0; + + // Calculate the various heat balance sums - // Calculate the predicted zone load to be provided by the system with the given desired zone air temperature - CalcPredictedSystemLoad(state, ZoneNum, RAFNFrac); + // NOTE: SumSysMCp and SumSysMCpT are not used in the predict step + this->calcZoneOrSpaceSums(state, false, zoneNum, spaceNum); - // Calculate the predicted zone load to be provided by the system with the given desired humidity ratio - CalcPredictedHumidityRatio(state, ZoneNum, RAFNFrac); + // Sum all convective internal gains except for people: SumIntGainExceptPeople + if (spaceNum == 0 && state.dataHybridModel->FlagHybridModel_PC) { + this->SumIntGainExceptPeople = 0.0; + this->SumIntGainExceptPeople = InternalHeatGains::SumAllInternalConvectionGainsExceptPeople(state, zoneNum); } - if (state.dataZoneTempPredictorCorrector->NumOnOffCtrZone > 0) { - for (RelativeZoneNum = 1; RelativeZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++RelativeZoneNum) { - if (TempControlledZone(RelativeZoneNum).DeltaTCutSet > 0.0) { - ZoneNum = TempControlledZone(RelativeZoneNum).ActualZoneNum; - if (TempControlledZone(RelativeZoneNum).CoolOffFlag && ZoneSysEnergyDemand(ZoneNum).TotalOutputRequired >= 0.0) { - TempControlledZone(RelativeZoneNum).CoolModeLast = true; - } else { - TempControlledZone(RelativeZoneNum).CoolModeLast = false; + this->TempDepCoef = this->SumHA + this->SumMCp; + this->TempIndCoef = this->SumIntGain + this->SumHATsurf - this->SumHATref + this->SumMCpT + this->SysDepZoneLoadsLagged; + this->TempHistoryTerm = this->AirPowerCap * (3.0 * this->ZTM[0] - (3.0 / 2.0) * this->ZTM[1] + (1.0 / 3.0) * this->ZTM[2]); + this->TempDepZnLd = (11.0 / 6.0) * this->AirPowerCap + this->TempDepCoef; + this->TempIndZnLd = this->TempHistoryTerm + this->TempIndCoef; + if (state.dataRoomAirMod->anyNonMixingRoomAirModel) { + if (state.dataRoomAirMod->AirModel(zoneNum).AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { + // RoomAirflowNetworkModel - make dynamic term independent of TimeStepSys + auto &thisRoomAirflowNetworkZoneInfo = state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(zoneNum); + if (thisRoomAirflowNetworkZoneInfo.IsUsed) { + int RoomAirNode = thisRoomAirflowNetworkZoneInfo.ControlAirNodeID; + RoomAirModelAirflowNetwork::LoadPredictionRoomAirModelAirflowNetwork(state, zoneNum, RoomAirNode); + this->TempDepCoef = + thisRoomAirflowNetworkZoneInfo.Node(RoomAirNode).SumHA + thisRoomAirflowNetworkZoneInfo.Node(RoomAirNode).SumLinkMCp; + this->TempIndCoef = thisRoomAirflowNetworkZoneInfo.Node(RoomAirNode).SumIntSensibleGain + + thisRoomAirflowNetworkZoneInfo.Node(RoomAirNode).SumHATsurf - + thisRoomAirflowNetworkZoneInfo.Node(RoomAirNode).SumHATref + + thisRoomAirflowNetworkZoneInfo.Node(RoomAirNode).SumLinkMCpT + + thisRoomAirflowNetworkZoneInfo.Node(RoomAirNode).SysDepZoneLoadsLagged; + this->AirPowerCap = thisRoomAirflowNetworkZoneInfo.Node(RoomAirNode).AirVolume * + state.dataHeatBal->Zone(zoneNum).ZoneVolCapMultpSens * thisRoomAirflowNetworkZoneInfo.Node(RoomAirNode).RhoAir * + thisRoomAirflowNetworkZoneInfo.Node(RoomAirNode).CpAir / + (state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour); + this->TempHistoryTerm = this->AirPowerCap * (3.0 * this->ZTM[0] - (3.0 / 2.0) * this->ZTM[1] + (1.0 / 3.0) * this->ZTM[2]); + this->TempDepZnLd = (11.0 / 6.0) * this->AirPowerCap + this->TempDepCoef; + this->TempIndZnLd = this->TempHistoryTerm + this->TempIndCoef; + if (thisRoomAirflowNetworkZoneInfo.Node(RoomAirNode).HasHVACAssigned) + RAFNFrac = thisRoomAirflowNetworkZoneInfo.Node(RoomAirNode).HVAC(1).SupplyFraction; + } + } + } + + // Exact solution or Euler method + state.dataHVACGlobal->ShortenTimeStepSysRoomAir = false; + if (state.dataHeatBal->ZoneAirSolutionAlgo != DataHeatBalance::SolutionAlgo::ThirdOrder) { + if (shortenTimeStepSys && state.dataHVACGlobal->TimeStepSys < state.dataGlobal->TimeStepZone) { + if (state.dataHVACGlobal->PreviousTimeStep < state.dataGlobal->TimeStepZone) { + this->ZoneT1 = this->ZoneTM2; + this->ZoneW1 = this->ZoneWM2; + if (state.dataRoomAirMod->AirModel(zoneNum).AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { + auto &thisRoomAirflowNetworkZoneInfo = state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(zoneNum); + for (int LoopNode = 1; LoopNode <= thisRoomAirflowNetworkZoneInfo.NumOfAirNodes; ++LoopNode) { + thisRoomAirflowNetworkZoneInfo.Node(LoopNode).AirTempT1 = thisRoomAirflowNetworkZoneInfo.Node(LoopNode).AirTempTM2; + thisRoomAirflowNetworkZoneInfo.Node(LoopNode).HumRatW1 = thisRoomAirflowNetworkZoneInfo.Node(LoopNode).HumRatWM2; + } } - if (TempControlledZone(RelativeZoneNum).HeatOffFlag && ZoneSysEnergyDemand(ZoneNum).TotalOutputRequired <= 0.0) { - TempControlledZone(RelativeZoneNum).HeatModeLast = true; - } else { - TempControlledZone(RelativeZoneNum).HeatModeLast = false; + } else { + this->ZoneT1 = this->ZoneTMX; + this->ZoneW1 = this->ZoneWMX; + if (state.dataRoomAirMod->AirModel(zoneNum).AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { + auto &thisRoomAirflowNetworkZoneInfo = state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(zoneNum); + for (int LoopNode = 1; LoopNode <= thisRoomAirflowNetworkZoneInfo.NumOfAirNodes; ++LoopNode) { + thisRoomAirflowNetworkZoneInfo.Node(LoopNode).AirTempT1 = thisRoomAirflowNetworkZoneInfo.Node(LoopNode).AirTempTMX; + thisRoomAirflowNetworkZoneInfo.Node(LoopNode).HumRatW1 = thisRoomAirflowNetworkZoneInfo.Node(LoopNode).HumRatWMX; + } + } + } + state.dataHVACGlobal->ShortenTimeStepSysRoomAir = true; + } else { + this->ZoneT1 = this->ZT; + this->ZoneW1 = this->ZoneAirHumRat; + if (state.dataRoomAirMod->AirModel(zoneNum).AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { + auto &thisRoomAirflowNetworkZoneInfo = state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(zoneNum); + for (int LoopNode = 1; LoopNode <= thisRoomAirflowNetworkZoneInfo.NumOfAirNodes; ++LoopNode) { + thisRoomAirflowNetworkZoneInfo.Node(LoopNode).AirTempT1 = thisRoomAirflowNetworkZoneInfo.Node(LoopNode).AirTemp; + thisRoomAirflowNetworkZoneInfo.Node(LoopNode).HumRatW1 = thisRoomAirflowNetworkZoneInfo.Node(LoopNode).HumRat; } } } + this->TempDepZnLd = this->TempDepCoef; + this->TempIndZnLd = this->TempIndCoef; } + + // Calculate the predicted zone load to be provided by the system with the given desired zone air temperature + this->calcPredictedSystemLoad(state, RAFNFrac, zoneNum, spaceNum); + + // Calculate the predicted zone load to be provided by the system with the given desired humidity ratio + this->calcPredictedHumidityRatio(state, RAFNFrac, zoneNum, spaceNum); } void CalcZoneAirTempSetPoints(EnergyPlusData &state) @@ -3985,9 +3594,6 @@ void CalcZoneAirTempSetPoints(EnergyPlusData &state) // This routine sets what the setpoints for each controlled zone should be based on schedules. // This is called each time step. - using ScheduleManager::GetCurrentScheduleValue; - using ScheduleManager::GetScheduleValuesForDay; - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: int RelativeZoneNum; int ActualZoneNum; @@ -4026,7 +3632,8 @@ void CalcZoneAirTempSetPoints(EnergyPlusData &state) // What if this zone not controlled??? ActualZoneNum = TempControlledZone(RelativeZoneNum).ActualZoneNum; TempControlSchedIndex = TempControlledZone(RelativeZoneNum).CTSchedIndex; - TempControlType(ActualZoneNum) = static_cast(GetCurrentScheduleValue(state, TempControlSchedIndex)); + 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 @@ -4035,7 +3642,7 @@ void CalcZoneAirTempSetPoints(EnergyPlusData &state) break; case DataHVACGlobals::ThermostatType::SingleHeating: SchedNameIndex = TempControlledZone(RelativeZoneNum).SchIndx_SingleHeatSetPoint; - TempZoneThermostatSetPoint(ActualZoneNum) = GetCurrentScheduleValue(state, SchedNameIndex); + TempZoneThermostatSetPoint(ActualZoneNum) = ScheduleManager::GetCurrentScheduleValue(state, SchedNameIndex); TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointLo = TempZoneThermostatSetPoint(ActualZoneNum); AdjustAirSetPointsforOpTempCntrl(state, RelativeZoneNum, ActualZoneNum, TempZoneThermostatSetPoint(ActualZoneNum)); @@ -4043,7 +3650,7 @@ void CalcZoneAirTempSetPoints(EnergyPlusData &state) break; case DataHVACGlobals::ThermostatType::SingleCooling: SchedNameIndex = TempControlledZone(RelativeZoneNum).SchIndx_SingleCoolSetPoint; - TempZoneThermostatSetPoint(ActualZoneNum) = GetCurrentScheduleValue(state, SchedNameIndex); + TempZoneThermostatSetPoint(ActualZoneNum) = ScheduleManager::GetCurrentScheduleValue(state, SchedNameIndex); TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointHi = TempZoneThermostatSetPoint(ActualZoneNum); // Added Jan 17 (X. Luo) @@ -4062,7 +3669,7 @@ void CalcZoneAirTempSetPoints(EnergyPlusData &state) SchedNameIndex = TempControlledZone(RelativeZoneNum).SchIndx_SingleHeatCoolSetPoint; - TempZoneThermostatSetPoint(ActualZoneNum) = GetCurrentScheduleValue(state, SchedNameIndex); + TempZoneThermostatSetPoint(ActualZoneNum) = ScheduleManager::GetCurrentScheduleValue(state, SchedNameIndex); // Added Jan 17 (X. Luo) // Adjust operative temperature based on adaptive comfort model @@ -4083,7 +3690,7 @@ void CalcZoneAirTempSetPoints(EnergyPlusData &state) DaySPValues.allocate(state.dataGlobal->NumOfTimeStepInHour, 24); } if (state.dataHVACGlobal->OptStartData.ActualZoneNum(ActualZoneNum) == ActualZoneNum) { - GetScheduleValuesForDay(state, SetPointTempSchedIndexCold, DaySPValues); + ScheduleManager::GetScheduleValuesForDay(state, SetPointTempSchedIndexCold, DaySPValues); OccStartTime = CEILING(state.dataHVACGlobal->OptStartData.OccStartTime(ActualZoneNum)) + 1; TempZoneThermostatSetPoint(ActualZoneNum) = DaySPValues(1, OccStartTime); } @@ -4099,7 +3706,7 @@ void CalcZoneAirTempSetPoints(EnergyPlusData &state) SetPointTempSchedIndexHot = TempControlledZone(RelativeZoneNum).SchIndx_DualSetPointWDeadBandHeat; SetPointTempSchedIndexCold = TempControlledZone(RelativeZoneNum).SchIndx_DualSetPointWDeadBandCool; - ZoneThermostatSetPointHi(ActualZoneNum) = GetCurrentScheduleValue(state, SetPointTempSchedIndexCold); + ZoneThermostatSetPointHi(ActualZoneNum) = ScheduleManager::GetCurrentScheduleValue(state, SetPointTempSchedIndexCold); TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointHi = ZoneThermostatSetPointHi(ActualZoneNum); // Added Jan 17 (X. Luo) @@ -4111,7 +3718,7 @@ void CalcZoneAirTempSetPoints(EnergyPlusData &state) AdjustAirSetPointsforOpTempCntrl(state, RelativeZoneNum, ActualZoneNum, ZoneThermostatSetPointHi(ActualZoneNum)); - ZoneThermostatSetPointLo(ActualZoneNum) = GetCurrentScheduleValue(state, SetPointTempSchedIndexHot); + ZoneThermostatSetPointLo(ActualZoneNum) = ScheduleManager::GetCurrentScheduleValue(state, SetPointTempSchedIndexHot); TempControlledZone(RelativeZoneNum).ZoneThermostatSetPointLo = ZoneThermostatSetPointLo(ActualZoneNum); AdjustAirSetPointsforOpTempCntrl(state, RelativeZoneNum, ActualZoneNum, ZoneThermostatSetPointLo(ActualZoneNum)); @@ -4122,10 +3729,10 @@ void CalcZoneAirTempSetPoints(EnergyPlusData &state) DaySPValues.allocate(state.dataGlobal->NumOfTimeStepInHour, 24); } if (state.dataHVACGlobal->OptStartData.ActualZoneNum(ActualZoneNum) == ActualZoneNum) { - GetScheduleValuesForDay(state, SetPointTempSchedIndexCold, DaySPValues); + ScheduleManager::GetScheduleValuesForDay(state, SetPointTempSchedIndexCold, DaySPValues); OccStartTime = CEILING(state.dataHVACGlobal->OptStartData.OccStartTime(ActualZoneNum)) + 1; state.dataZoneCtrls->OccRoomTSetPointCool(ActualZoneNum) = DaySPValues(1, OccStartTime); - GetScheduleValuesForDay(state, SetPointTempSchedIndexHot, DaySPValues); + ScheduleManager::GetScheduleValuesForDay(state, SetPointTempSchedIndexHot, DaySPValues); state.dataZoneCtrls->OccRoomTSetPointHeat(ActualZoneNum) = DaySPValues(1, OccStartTime); } @@ -4158,13 +3765,14 @@ void CalcZoneAirTempSetPoints(EnergyPlusData &state) state.dataFaultsMgr->FaultsThermostatOffset(iFault).FaultyThermostatName)) { // Check fault availability schedules - if (GetCurrentScheduleValue(state, state.dataFaultsMgr->FaultsThermostatOffset(iFault).AvaiSchedPtr) > 0.0) { + if (ScheduleManager::GetCurrentScheduleValue(state, state.dataFaultsMgr->FaultsThermostatOffset(iFault).AvaiSchedPtr) > 0.0) { // Check fault severity schedules to update the reference thermostat offset double rSchVal = 1.0; double offsetUpdated; if (state.dataFaultsMgr->FaultsThermostatOffset(iFault).SeveritySchedPtr >= 0) { - rSchVal = GetCurrentScheduleValue(state, state.dataFaultsMgr->FaultsThermostatOffset(iFault).SeveritySchedPtr); + rSchVal = + ScheduleManager::GetCurrentScheduleValue(state, state.dataFaultsMgr->FaultsThermostatOffset(iFault).SeveritySchedPtr); } offsetUpdated = rSchVal * state.dataFaultsMgr->FaultsThermostatOffset(iFault).Offset; @@ -4185,462 +3793,47 @@ void CalcZoneAirTempSetPoints(EnergyPlusData &state) OverrideAirSetPointsforEMSCntrl(state); } -void CalcPredictedSystemLoad(EnergyPlusData &state, int const ZoneNum, Real64 RAFNFrac) +void ZoneSpaceHeatBalanceData::calcPredictedHumidityRatio(EnergyPlusData &state, Real64 const RAFNFrac, int const zoneNum, int const spaceNum) { // SUBROUTINE INFORMATION: - // AUTHOR Russ Taylor - // DATE WRITTEN Nov 1997 - // MODIFIED na - // RE-ENGINEERED na + // AUTHOR Richard J. Liesen + // DATE WRITTEN May 2001 // PURPOSE OF THIS SUBROUTINE: - // This subroutine calculates the predicted system load for a time step. + // This subroutine does the prediction step for humidity control - using ScheduleManager::GetCurrentScheduleValue; + // METHODOLOGY EMPLOYED: + // This solves for the required system moisture required to try and achieve the desired + // Humidity Ratio in the Zone - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - Real64 LoadToHeatingSetPoint; - Real64 LoadToCoolingSetPoint; - Real64 ZoneSetPoint; + // REFERENCES: + // Routine FinalZnCalcs - FINAL ZONE CALCULATIONS, authored by Dale Herron + // for BLAST. - auto &Zone = state.dataHeatBal->Zone; - auto &TempZoneThermostatSetPoint = state.dataHeatBalFanSys->TempZoneThermostatSetPoint; - auto &ZoneThermostatSetPointLo = state.dataHeatBalFanSys->ZoneThermostatSetPointLo; - auto &ZoneThermostatSetPointHi = state.dataHeatBalFanSys->ZoneThermostatSetPointHi; - auto &TempDepZnLd = state.dataZoneTempPredictorCorrector->TempDepZnLd; - auto &TempIndZnLd = state.dataZoneTempPredictorCorrector->TempIndZnLd; - auto &ZoneSysEnergyDemand = state.dataZoneEnergyDemand->ZoneSysEnergyDemand; - auto &ZoneT1 = state.dataHeatBalFanSys->ZoneT1; - auto &Node = state.dataLoopNodes->Node; - auto &ZoneAirSolutionAlgo = state.dataHeatBal->ZoneAirSolutionAlgo; - auto &AIRRAT = state.dataHeatBalFanSys->AIRRAT; - - state.dataZoneEnergyDemand->DeadBandOrSetback(ZoneNum) = false; - ZoneSetPoint = 0.0; - LoadToHeatingSetPoint = 0.0; - LoadToCoolingSetPoint = 0.0; - - switch (state.dataHeatBalFanSys->TempControlType(ZoneNum)) { - case DataHVACGlobals::ThermostatType::Uncontrolled: - // Uncontrolled Zone - LoadToHeatingSetPoint = 0.0; - LoadToCoolingSetPoint = 0.0; - ZoneSysEnergyDemand(ZoneNum).TotalOutputRequired = 0.0; - break; - case DataHVACGlobals::ThermostatType::SingleHeating: - if (ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::ThirdOrder) { - LoadToHeatingSetPoint = (TempDepZnLd(ZoneNum) * TempZoneThermostatSetPoint(ZoneNum) - TempIndZnLd(ZoneNum)); - // Exact solution - } else if (ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::AnalyticalSolution) { - if (TempDepZnLd(ZoneNum) == 0.0) { // B=0 - LoadToHeatingSetPoint = AIRRAT(ZoneNum) * (TempZoneThermostatSetPoint(ZoneNum) - ZoneT1(ZoneNum)) - TempIndZnLd(ZoneNum); - } else { - Real64 const exp_700_TA(std::exp(min(700.0, -TempDepZnLd(ZoneNum) / AIRRAT(ZoneNum)))); - LoadToHeatingSetPoint = - TempDepZnLd(ZoneNum) * (TempZoneThermostatSetPoint(ZoneNum) - ZoneT1(ZoneNum) * exp_700_TA) / (1.0 - exp_700_TA) - - TempIndZnLd(ZoneNum); - } - } else if (ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::EulerMethod) { - LoadToHeatingSetPoint = AIRRAT(ZoneNum) * (TempZoneThermostatSetPoint(ZoneNum) - ZoneT1(ZoneNum)) + - TempDepZnLd(ZoneNum) * (TempZoneThermostatSetPoint(ZoneNum)) - TempIndZnLd(ZoneNum); - } - if (RAFNFrac > 0.0) LoadToHeatingSetPoint = LoadToHeatingSetPoint / RAFNFrac; - ZoneSysEnergyDemand(ZoneNum).TotalOutputRequired = LoadToHeatingSetPoint; - ZoneSetPoint = TempZoneThermostatSetPoint(ZoneNum); - LoadToCoolingSetPoint = LoadToHeatingSetPoint; - // for consistency with the other cases, use LE instead of LT and don't subtract 1.0 Watt as a way of pushing the zero load - // case over the threshold - if ((ZoneSysEnergyDemand(ZoneNum).TotalOutputRequired) <= 0.0) state.dataZoneEnergyDemand->DeadBandOrSetback(ZoneNum) = true; + static constexpr std::string_view RoutineName("calcPredictedHumidityRatio"); - break; - case DataHVACGlobals::ThermostatType::SingleCooling: - if (ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::ThirdOrder) { - LoadToCoolingSetPoint = TempDepZnLd(ZoneNum) * TempZoneThermostatSetPoint(ZoneNum) - TempIndZnLd(ZoneNum); - } else if (ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::AnalyticalSolution) { - if (TempDepZnLd(ZoneNum) == 0.0) { // B=0 - LoadToCoolingSetPoint = AIRRAT(ZoneNum) * (TempZoneThermostatSetPoint(ZoneNum) - ZoneT1(ZoneNum)) - TempIndZnLd(ZoneNum); - } else { - Real64 const exp_700_TA(std::exp(min(700.0, -TempDepZnLd(ZoneNum) / AIRRAT(ZoneNum)))); - LoadToCoolingSetPoint = - TempDepZnLd(ZoneNum) * (TempZoneThermostatSetPoint(ZoneNum) - ZoneT1(ZoneNum) * exp_700_TA) / (1.0 - exp_700_TA) - - TempIndZnLd(ZoneNum); - } - } else if (ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::EulerMethod) { - LoadToCoolingSetPoint = AIRRAT(ZoneNum) * (TempZoneThermostatSetPoint(ZoneNum) - ZoneT1(ZoneNum)) + - TempDepZnLd(ZoneNum) * TempZoneThermostatSetPoint(ZoneNum) - TempIndZnLd(ZoneNum); + Real64 ZoneRHHumidifyingSetPoint = 0.0; // Zone humidifying set point (%) + Real64 ZoneRHDehumidifyingSetPoint = 0.0; // Zone dehumidifying set point (%) + + auto &thisZone = state.dataHeatBal->Zone(zoneNum); + bool SingleSetPoint = false; // This determines whether both setpoint are equal or not + + // Check to see if this is a "humidity controlled zone" + bool ControlledHumidZoneFlag = false; + // Check all the controlled zones to see if it matches the zone simulated + if (thisZone.humidityControlZoneIndex > 0) { + auto &humidityControlZone = state.dataZoneCtrls->HumidityControlZone(thisZone.humidityControlZoneIndex); + assert(humidityControlZone.ActualZoneNum == zoneNum); + ZoneRHHumidifyingSetPoint = ScheduleManager::GetCurrentScheduleValue(state, humidityControlZone.HumidifyingSchedIndex); + ZoneRHDehumidifyingSetPoint = ScheduleManager::GetCurrentScheduleValue(state, humidityControlZone.DehumidifyingSchedIndex); + + // Apply EMS values to overwrite the humidistat values + if (humidityControlZone.EMSOverrideHumidifySetPointOn) { + ZoneRHHumidifyingSetPoint = humidityControlZone.EMSOverrideHumidifySetPointValue; } - if (RAFNFrac > 0.0) LoadToHeatingSetPoint = LoadToHeatingSetPoint / RAFNFrac; - if (Zone(ZoneNum).HasAdjustedReturnTempByITE && !(state.dataGlobal->BeginSimFlag)) { - LoadToCoolingSetPoint = TempDepZnLd(ZoneNum) * Zone(ZoneNum).AdjustedReturnTempByITE - TempIndZnLd(ZoneNum); - } - ZoneSysEnergyDemand(ZoneNum).TotalOutputRequired = LoadToCoolingSetPoint; - ZoneSetPoint = TempZoneThermostatSetPoint(ZoneNum); - LoadToHeatingSetPoint = LoadToCoolingSetPoint; - // for consistency with the other cases, use GE instead of GT and don't add 1.0 Watt as a way of pushing the zero load - // case over the threshold - if ((ZoneSysEnergyDemand(ZoneNum).TotalOutputRequired) >= 0.0) state.dataZoneEnergyDemand->DeadBandOrSetback(ZoneNum) = true; - break; - case DataHVACGlobals::ThermostatType::SingleHeatCool: - if (ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::ThirdOrder) { - LoadToHeatingSetPoint = (TempDepZnLd(ZoneNum) * (TempZoneThermostatSetPoint(ZoneNum)) - TempIndZnLd(ZoneNum)); - LoadToCoolingSetPoint = (TempDepZnLd(ZoneNum) * (TempZoneThermostatSetPoint(ZoneNum)) - TempIndZnLd(ZoneNum)); - // Exact solution - } else if (ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::AnalyticalSolution) { - if (TempDepZnLd(ZoneNum) == 0.0) { // B=0 - LoadToHeatingSetPoint = AIRRAT(ZoneNum) * (TempZoneThermostatSetPoint(ZoneNum) - ZoneT1(ZoneNum)) - TempIndZnLd(ZoneNum); - LoadToCoolingSetPoint = AIRRAT(ZoneNum) * (TempZoneThermostatSetPoint(ZoneNum) - ZoneT1(ZoneNum)) - TempIndZnLd(ZoneNum); - } else { - Real64 const exp_700_TA(std::exp(min(700.0, -TempDepZnLd(ZoneNum) / AIRRAT(ZoneNum)))); - LoadToHeatingSetPoint = - TempDepZnLd(ZoneNum) * (TempZoneThermostatSetPoint(ZoneNum) - ZoneT1(ZoneNum) * exp_700_TA) / (1.0 - exp_700_TA) - - TempIndZnLd(ZoneNum); - LoadToCoolingSetPoint = - TempDepZnLd(ZoneNum) * (TempZoneThermostatSetPoint(ZoneNum) - ZoneT1(ZoneNum) * exp_700_TA) / (1.0 - exp_700_TA) - - TempIndZnLd(ZoneNum); - } - } else if (ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::EulerMethod) { - LoadToHeatingSetPoint = AIRRAT(ZoneNum) * (TempZoneThermostatSetPoint(ZoneNum) - ZoneT1(ZoneNum)) + - TempDepZnLd(ZoneNum) * TempZoneThermostatSetPoint(ZoneNum) - TempIndZnLd(ZoneNum); - LoadToCoolingSetPoint = AIRRAT(ZoneNum) * (TempZoneThermostatSetPoint(ZoneNum) - ZoneT1(ZoneNum)) + - TempDepZnLd(ZoneNum) * TempZoneThermostatSetPoint(ZoneNum) - TempIndZnLd(ZoneNum); - } - ZoneSetPoint = TempZoneThermostatSetPoint(ZoneNum); - if (RAFNFrac > 0.0) LoadToHeatingSetPoint = LoadToHeatingSetPoint / RAFNFrac; - if (RAFNFrac > 0.0) LoadToCoolingSetPoint = LoadToCoolingSetPoint / RAFNFrac; - - if (Zone(ZoneNum).HasAdjustedReturnTempByITE && !(state.dataGlobal->BeginSimFlag)) { - LoadToCoolingSetPoint = TempDepZnLd(ZoneNum) * Zone(ZoneNum).AdjustedReturnTempByITE - TempIndZnLd(ZoneNum); - } - - // Note that LoadToHeatingSetPoint is generally not equal to LoadToCoolingSetPoint - // when the heating and cooling set-points are equal if the zone is unmixed, - // e.g. displacement ventilation or UFAD, since the stratification is generally not the same in heating and cooling modes - - // Possible combinations: - // 1/ LoadToHeatingSetPoint > 0 & LoadToCoolingSetPoint > 0 --> Heating required - // 2/ LoadToHeatingSetPoint > LoadToCoolingSetPoint --> Possible in the unmixed case but should be trapped - // as a poor choice of set-points - // 3/ LoadToHeatingSetPoint < 0 & LoadToCoolingSetPoint < 0 --> Cooling Required - // 4/ LoadToHeatingSetPoint <=0 & LoadToCoolingSetPoint >=0 --> Dead Band Operation ! includes zero load cases - // First trap bad set-points - if (LoadToHeatingSetPoint > LoadToCoolingSetPoint) { - ShowSevereError( - state, - "DataHVACGlobals::ThermostatType::SingleHeatCool: Effective heating set-point higher than effective cooling set-point - use " - "DualSetPointWithDeadBand if using unmixed air model"); - ShowContinueErrorTimeStamp(state, "occurs in Zone=" + Zone(ZoneNum).Name); - ShowContinueError(state, - format("LoadToHeatingSetPoint={:.3R}, LoadToCoolingSetPoint={:.3R}", LoadToHeatingSetPoint, LoadToCoolingSetPoint)); - ShowContinueError(state, format("Zone TempDepZnLd={:.2R}", TempDepZnLd(ZoneNum))); - ShowContinueError(state, format("Zone TempIndZnLd={:.2R}", TempIndZnLd(ZoneNum))); - ShowContinueError(state, format("Zone ThermostatSetPoint={:.2R}", TempZoneThermostatSetPoint(ZoneNum))); - ShowFatalError(state, "Program terminates due to above conditions."); - } - - if (LoadToHeatingSetPoint > 0.0 && LoadToCoolingSetPoint > 0.0) { - ZoneSysEnergyDemand(ZoneNum).TotalOutputRequired = LoadToHeatingSetPoint; - } else if (LoadToHeatingSetPoint < 0.0 && LoadToCoolingSetPoint < 0.0) { - ZoneSysEnergyDemand(ZoneNum).TotalOutputRequired = LoadToCoolingSetPoint; - } else if (LoadToHeatingSetPoint <= 0.0 && LoadToCoolingSetPoint >= 0.0) { // deadband includes zero loads - ZoneSysEnergyDemand(ZoneNum).TotalOutputRequired = 0.0; - if (Zone(ZoneNum).SystemZoneNodeNumber > 0) { - ZoneSetPoint = Node(Zone(ZoneNum).SystemZoneNodeNumber).Temp; - ZoneSetPoint = max(ZoneSetPoint, ZoneThermostatSetPointLo(ZoneNum)); // trap out of deadband - ZoneSetPoint = min(ZoneSetPoint, ZoneThermostatSetPointHi(ZoneNum)); // trap out of deadband - } - state.dataZoneEnergyDemand->DeadBandOrSetback(ZoneNum) = true; - } else { // this should never occur! - ShowSevereError(state, - "SingleHeatCoolSetPoint: Unanticipated combination of heating and cooling loads - report to EnergyPlus Development Team"); - ShowContinueErrorTimeStamp(state, "occurs in Zone=" + Zone(ZoneNum).Name); - ShowContinueError(state, - format("LoadToHeatingSetPoint={:.3R}, LoadToCoolingSetPoint={:.3R}", LoadToHeatingSetPoint, LoadToCoolingSetPoint)); - ShowContinueError(state, format("Zone TempDepZnLd={:.2R}", TempDepZnLd(ZoneNum))); - ShowContinueError(state, format("Zone TempIndZnLd={:.2R}", TempIndZnLd(ZoneNum))); - ShowContinueError(state, format("Zone ThermostatSetPoint={:.2R}", TempZoneThermostatSetPoint(ZoneNum))); - ShowFatalError(state, "Program terminates due to above conditions."); - } - break; - case DataHVACGlobals::ThermostatType::DualSetPointWithDeadBand: - if (ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::ThirdOrder) { - LoadToHeatingSetPoint = (TempDepZnLd(ZoneNum) * (ZoneThermostatSetPointLo(ZoneNum)) - TempIndZnLd(ZoneNum)); - LoadToCoolingSetPoint = (TempDepZnLd(ZoneNum) * (ZoneThermostatSetPointHi(ZoneNum)) - TempIndZnLd(ZoneNum)); - // Exact solution - } else if (ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::AnalyticalSolution) { - if (TempDepZnLd(ZoneNum) == 0.0) { // B=0 - LoadToHeatingSetPoint = AIRRAT(ZoneNum) * (ZoneThermostatSetPointLo(ZoneNum) - ZoneT1(ZoneNum)) - TempIndZnLd(ZoneNum); - LoadToCoolingSetPoint = AIRRAT(ZoneNum) * (ZoneThermostatSetPointHi(ZoneNum) - ZoneT1(ZoneNum)) - TempIndZnLd(ZoneNum); - } else { - Real64 const exp_700_TA(std::exp(min(700.0, -TempDepZnLd(ZoneNum) / AIRRAT(ZoneNum)))); - LoadToHeatingSetPoint = - TempDepZnLd(ZoneNum) * (ZoneThermostatSetPointLo(ZoneNum) - ZoneT1(ZoneNum) * exp_700_TA) / (1.0 - exp_700_TA) - - TempIndZnLd(ZoneNum); - LoadToCoolingSetPoint = - TempDepZnLd(ZoneNum) * (ZoneThermostatSetPointHi(ZoneNum) - ZoneT1(ZoneNum) * exp_700_TA) / (1.0 - exp_700_TA) - - TempIndZnLd(ZoneNum); - } - } else if (ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::EulerMethod) { - LoadToHeatingSetPoint = AIRRAT(ZoneNum) * (ZoneThermostatSetPointLo(ZoneNum) - ZoneT1(ZoneNum)) + - TempDepZnLd(ZoneNum) * ZoneThermostatSetPointLo(ZoneNum) - TempIndZnLd(ZoneNum); - LoadToCoolingSetPoint = AIRRAT(ZoneNum) * (ZoneThermostatSetPointHi(ZoneNum) - ZoneT1(ZoneNum)) + - TempDepZnLd(ZoneNum) * ZoneThermostatSetPointHi(ZoneNum) - TempIndZnLd(ZoneNum); - } - if (RAFNFrac > 0.0) LoadToHeatingSetPoint = LoadToHeatingSetPoint / RAFNFrac; - if (RAFNFrac > 0.0) LoadToCoolingSetPoint = LoadToCoolingSetPoint / RAFNFrac; - - if (Zone(ZoneNum).HasAdjustedReturnTempByITE && !(state.dataGlobal->BeginSimFlag)) { - LoadToCoolingSetPoint = TempDepZnLd(ZoneNum) * Zone(ZoneNum).AdjustedReturnTempByITE - TempIndZnLd(ZoneNum); - } - - // Possible combinations: - // 1/ LoadToHeatingSetPoint > 0 & LoadToCoolingSetPoint > 0 --> Heating required - // 2/ LoadToHeatingSetPoint > LoadToCoolingSetPoint --> Possible in the unmixed case but should be trapped - // as a poor choice of set-points - // 3/ LoadToHeatingSetPoint < 0 & LoadToCoolingSetPoint < 0 --> Cooling Required - // 4/ LoadToHeatingSetPoint <=0 & LoadToCoolingSetPoint >=0 --> Dead Band Operation - includes zero load cases - // First trap bad set-points - if (LoadToHeatingSetPoint > LoadToCoolingSetPoint) { - ShowSevereError(state, - "DualSetPointWithDeadBand: Effective heating set-point higher than effective cooling set-point - increase " - "deadband if using unmixed air model"); - ShowContinueErrorTimeStamp(state, "occurs in Zone=" + Zone(ZoneNum).Name); - ShowContinueError(state, - format("LoadToHeatingSetPoint={:.3R}, LoadToCoolingSetPoint={:.3R}", LoadToHeatingSetPoint, LoadToCoolingSetPoint)); - ShowContinueError(state, format("Zone TempDepZnLd={:.2R}", TempDepZnLd(ZoneNum))); - ShowContinueError(state, format("Zone TempIndZnLd={:.2R}", TempIndZnLd(ZoneNum))); - ShowContinueError(state, format("Zone Heating ThermostatSetPoint={:.2R}", ZoneThermostatSetPointLo(ZoneNum))); - ShowContinueError(state, format("Zone Cooling ThermostatSetPoint={:.2R}", ZoneThermostatSetPointHi(ZoneNum))); - ShowFatalError(state, "Program terminates due to above conditions."); - } - - if (LoadToHeatingSetPoint > 0.0 && LoadToCoolingSetPoint > 0.0) { - ZoneSysEnergyDemand(ZoneNum).TotalOutputRequired = LoadToHeatingSetPoint; - ZoneSetPoint = ZoneThermostatSetPointLo(ZoneNum); - } else if (LoadToHeatingSetPoint < 0.0 && LoadToCoolingSetPoint < 0.0) { - ZoneSysEnergyDemand(ZoneNum).TotalOutputRequired = LoadToCoolingSetPoint; - ZoneSetPoint = ZoneThermostatSetPointHi(ZoneNum); - } else if (LoadToHeatingSetPoint <= 0.0 && LoadToCoolingSetPoint >= 0.0) { // deadband includes zero loads - // this turns out to cause instabilities sometimes? that lead to setpoint errors if predictor is off. - ZoneSysEnergyDemand(ZoneNum).TotalOutputRequired = 0.0; - if (Zone(ZoneNum).SystemZoneNodeNumber > 0) { - ZoneSetPoint = Node(Zone(ZoneNum).SystemZoneNodeNumber).Temp; - ZoneSetPoint = max(ZoneSetPoint, ZoneThermostatSetPointLo(ZoneNum)); // trap out of deadband - ZoneSetPoint = min(ZoneSetPoint, ZoneThermostatSetPointHi(ZoneNum)); // trap out of deadband - } - state.dataZoneEnergyDemand->DeadBandOrSetback(ZoneNum) = true; - } else { // this should never occur! - ShowSevereError( - state, "DualSetPointWithDeadBand: Unanticipated combination of heating and cooling loads - report to EnergyPlus Development Team"); - ShowContinueErrorTimeStamp(state, "occurs in Zone=" + Zone(ZoneNum).Name); - ShowContinueError(state, - format("LoadToHeatingSetPoint={:.3R}, LoadToCoolingSetPoint={:.3R}", LoadToHeatingSetPoint, LoadToCoolingSetPoint)); - ShowContinueError(state, format("Zone Heating Set-point={:.2R}", ZoneThermostatSetPointLo(ZoneNum))); - ShowContinueError(state, format("Zone Cooling Set-point={:.2R}", ZoneThermostatSetPointHi(ZoneNum))); - ShowContinueError(state, format("Zone TempDepZnLd={:.2R}", TempDepZnLd(ZoneNum))); - ShowContinueError(state, format("Zone TempIndZnLd={:.2R}", TempIndZnLd(ZoneNum))); - ShowContinueError(state, format("Zone ThermostatSetPoint={:.2R}", TempZoneThermostatSetPoint(ZoneNum))); - - ShowFatalError(state, "Program terminates due to above conditions."); - } - break; - default: - break; - } - - // Staged control zone - if (state.dataZoneTempPredictorCorrector->NumStageCtrZone > 0) { - if (state.dataZoneCtrls->StageZoneLogic(ZoneNum)) { - if (ZoneSysEnergyDemand(ZoneNum).StageNum == 0) { // No load - LoadToHeatingSetPoint = 0.0; - LoadToCoolingSetPoint = 0.0; - ZoneSysEnergyDemand(ZoneNum).TotalOutputRequired = 0.0; - if (Zone(ZoneNum).SystemZoneNodeNumber > 0) { - ZoneSetPoint = Node(Zone(ZoneNum).SystemZoneNodeNumber).Temp; - ZoneSetPoint = max(ZoneSetPoint, ZoneThermostatSetPointLo(ZoneNum)); // trap out of deadband - ZoneSetPoint = min(ZoneSetPoint, ZoneThermostatSetPointHi(ZoneNum)); // trap out of deadband - } - state.dataZoneEnergyDemand->DeadBandOrSetback(ZoneNum) = true; - } else if (ZoneSysEnergyDemand(ZoneNum).StageNum < 0) { // Cooling load - if (ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::ThirdOrder) { - LoadToCoolingSetPoint = (TempDepZnLd(ZoneNum) * (ZoneThermostatSetPointHi(ZoneNum)) - TempIndZnLd(ZoneNum)); - } else if (ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::AnalyticalSolution) { - if (TempDepZnLd(ZoneNum) == 0.0) { // B=0 - LoadToCoolingSetPoint = AIRRAT(ZoneNum) * (ZoneThermostatSetPointHi(ZoneNum) - ZoneT1(ZoneNum)) - TempIndZnLd(ZoneNum); - } else { - Real64 const exp_700_TA(std::exp(min(700.0, -TempDepZnLd(ZoneNum) / AIRRAT(ZoneNum)))); - LoadToCoolingSetPoint = - TempDepZnLd(ZoneNum) * (ZoneThermostatSetPointHi(ZoneNum) - ZoneT1(ZoneNum) * exp_700_TA) / (1.0 - exp_700_TA) - - TempIndZnLd(ZoneNum); - } - } else if (ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::EulerMethod) { - LoadToCoolingSetPoint = AIRRAT(ZoneNum) * (ZoneThermostatSetPointHi(ZoneNum) - ZoneT1(ZoneNum)) + - TempDepZnLd(ZoneNum) * ZoneThermostatSetPointHi(ZoneNum) - TempIndZnLd(ZoneNum); - } - ZoneSysEnergyDemand(ZoneNum).TotalOutputRequired = LoadToCoolingSetPoint; - ZoneSetPoint = ZoneThermostatSetPointHi(ZoneNum); - LoadToHeatingSetPoint = LoadToCoolingSetPoint; - if ((ZoneSysEnergyDemand(ZoneNum).TotalOutputRequired) >= 0.0) state.dataZoneEnergyDemand->DeadBandOrSetback(ZoneNum) = true; - } else { // Heating load - if (ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::ThirdOrder) { - LoadToHeatingSetPoint = (TempDepZnLd(ZoneNum) * ZoneThermostatSetPointLo(ZoneNum) - TempIndZnLd(ZoneNum)); - // Exact solution - } else if (ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::AnalyticalSolution) { - if (TempDepZnLd(ZoneNum) == 0.0) { // B=0 - LoadToHeatingSetPoint = AIRRAT(ZoneNum) * (ZoneThermostatSetPointLo(ZoneNum) - ZoneT1(ZoneNum)) - TempIndZnLd(ZoneNum); - } else { - Real64 const exp_700_TA(std::exp(min(700.0, -TempDepZnLd(ZoneNum) / AIRRAT(ZoneNum)))); - LoadToHeatingSetPoint = - TempDepZnLd(ZoneNum) * (ZoneThermostatSetPointLo(ZoneNum) - ZoneT1(ZoneNum) * exp_700_TA) / (1.0 - exp_700_TA) - - TempIndZnLd(ZoneNum); - } - } else if (ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::EulerMethod) { - LoadToHeatingSetPoint = AIRRAT(ZoneNum) * (ZoneThermostatSetPointLo(ZoneNum) - ZoneT1(ZoneNum)) + - TempDepZnLd(ZoneNum) * (ZoneThermostatSetPointLo(ZoneNum)) - TempIndZnLd(ZoneNum); - } - ZoneSysEnergyDemand(ZoneNum).TotalOutputRequired = LoadToHeatingSetPoint; - ZoneSetPoint = ZoneThermostatSetPointLo(ZoneNum); - LoadToCoolingSetPoint = LoadToHeatingSetPoint; - if ((ZoneSysEnergyDemand(ZoneNum).TotalOutputRequired) <= 0.0) state.dataZoneEnergyDemand->DeadBandOrSetback(ZoneNum) = true; - } - } - } - - // If the ZoneNodeNum has been set for a Controlled Zone, then the zone setpoint is placed on the node. - if (Zone(ZoneNum).SystemZoneNodeNumber > 0) { - Node(Zone(ZoneNum).SystemZoneNodeNumber).TempSetPoint = ZoneSetPoint; - } - - if (ZoneSetPoint > state.dataZoneTempPredictorCorrector->ZoneSetPointLast(ZoneNum)) { - state.dataZoneEnergyDemand->Setback(ZoneNum) = true; - } else { - state.dataZoneEnergyDemand->Setback(ZoneNum) = false; - } - - state.dataZoneTempPredictorCorrector->ZoneSetPointLast(ZoneNum) = ZoneSetPoint; - TempZoneThermostatSetPoint(ZoneNum) = ZoneSetPoint; // needed to fix Issue # 5048 - state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum) = state.dataZoneEnergyDemand->DeadBandOrSetback(ZoneNum); - - // Apply the Zone Multiplier and Load Correction factor as needed - ReportSensibleLoadsZoneMultiplier(ZoneSysEnergyDemand(ZoneNum).TotalOutputRequired, - ZoneSysEnergyDemand(ZoneNum).OutputRequiredToHeatingSP, - ZoneSysEnergyDemand(ZoneNum).OutputRequiredToCoolingSP, - state.dataHeatBal->ZoneSNLoadPredictedRate(ZoneNum), - state.dataHeatBal->ZoneSNLoadPredictedHSPRate(ZoneNum), - state.dataHeatBal->ZoneSNLoadPredictedCSPRate(ZoneNum), - LoadToHeatingSetPoint, - LoadToCoolingSetPoint, - state.dataHeatBalFanSys->LoadCorrectionFactor(ZoneNum), - Zone(ZoneNum).Multiplier, - Zone(ZoneNum).ListMultiplier); - - // init each sequenced demand to the full output - if (allocated(ZoneSysEnergyDemand(ZoneNum).SequencedOutputRequired)) - ZoneSysEnergyDemand(ZoneNum).SequencedOutputRequired = ZoneSysEnergyDemand(ZoneNum).TotalOutputRequired; // array assignment - if (allocated(ZoneSysEnergyDemand(ZoneNum).SequencedOutputRequiredToHeatingSP)) - ZoneSysEnergyDemand(ZoneNum).SequencedOutputRequiredToHeatingSP = ZoneSysEnergyDemand(ZoneNum).OutputRequiredToHeatingSP; // array assignment - if (allocated(ZoneSysEnergyDemand(ZoneNum).SequencedOutputRequiredToCoolingSP)) - ZoneSysEnergyDemand(ZoneNum).SequencedOutputRequiredToCoolingSP = ZoneSysEnergyDemand(ZoneNum).OutputRequiredToCoolingSP; // array assignment -} - -void ReportSensibleLoadsZoneMultiplier(Real64 &TotalLoad, - Real64 &TotalHeatLoad, - Real64 &TotalCoolLoad, - Real64 &SensLoadSingleZone, - Real64 &SensLoadHeatSingleZone, - Real64 &SensLoadCoolSingleZone, - Real64 const OutputHeatSP, - Real64 const OutputCoolSP, - Real64 const LoadCorrFactor, - Real64 const ZoneMultiplier, - Real64 const ZoneMultiplierList) -{ - SensLoadSingleZone = TotalLoad * LoadCorrFactor; - SensLoadHeatSingleZone = OutputHeatSP * LoadCorrFactor; - SensLoadCoolSingleZone = OutputCoolSP * LoadCorrFactor; - - Real64 ZoneMultFac = ZoneMultiplier * ZoneMultiplierList; - - TotalLoad = SensLoadSingleZone * ZoneMultFac; - TotalHeatLoad = SensLoadHeatSingleZone * ZoneMultFac; - TotalCoolLoad = SensLoadCoolSingleZone * ZoneMultFac; -} - -void CalcPredictedHumidityRatio(EnergyPlusData &state, int const ZoneNum, Real64 RAFNFrac) -{ - - // SUBROUTINE INFORMATION: - // AUTHOR Richard J. Liesen - // DATE WRITTEN May 2001 - // MODIFIED na - // RE-ENGINEERED na - - // PURPOSE OF THIS SUBROUTINE: - // This subroutine does the prediction step for humidity control - - // METHODOLOGY EMPLOYED: - // This solves for the required system moisture required to try and achieve the desired - // Humidity Ratio in the Zone - - // REFERENCES: - // Routine FinalZnCalcs - FINAL ZONE CALCULATIONS, authored by Dale Herron - // for BLAST. - - // Using/Aliasing - using ScheduleManager::GetCurrentScheduleValue; - - // SUBROUTINE PARAMETER DEFINITIONS: - static constexpr std::string_view RoutineName("CalcPredictedHumidityRatio"); - - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - Real64 LatentGain; // Zone latent load - Real64 RhoAir; - Real64 A; - Real64 B; - Real64 C; - Real64 SysTimeStepInSeconds; - Real64 H2OHtOfVap; - Real64 RHSetPoint; // Relative Humidity in percent - Real64 WZoneSetPoint; - int HumidControlledZoneNum; - bool ControlledHumidZoneFlag; // This determines whether this is a humidity controlled zone or not - Real64 ZoneRHHumidifyingSetPoint; // Zone humidifying set point (%) - Real64 ZoneRHDehumidifyingSetPoint; // Zone dehumidifying set point (%) - Real64 LoadToHumidifySetPoint; // Moisture load at humidifying set point - Real64 LoadToDehumidifySetPoint; // Moisture load at dehumidifying set point - Real64 ZoneAirRH; // Zone air relative humidity - bool SingleSetPoint; // This determines whether both setpoint are equal or not - int RoomAirNode; - - auto &zone = state.dataHeatBal->Zone(ZoneNum); - auto &ZT = state.dataHeatBalFanSys->ZT(ZoneNum); - auto &MAT = state.dataHeatBalFanSys->MAT(ZoneNum); - auto &zoneAirHumRat = state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum); - auto &zoneSysMoistureDemand = state.dataZoneEnergyDemand->ZoneSysMoistureDemand(ZoneNum); - - LoadToHumidifySetPoint = 0.0; - LoadToDehumidifySetPoint = 0.0; - SingleSetPoint = false; - zoneSysMoistureDemand.TotalOutputRequired = 0.0; - zoneSysMoistureDemand.OutputRequiredToHumidifyingSP = 0.0; - zoneSysMoistureDemand.OutputRequiredToDehumidifyingSP = 0.0; - - // Check to see if this is a "humidity controlled zone" - ControlledHumidZoneFlag = false; - // Check all the controlled zones to see if it matches the zone simulated - for (HumidControlledZoneNum = 1; HumidControlledZoneNum <= state.dataZoneCtrls->NumHumidityControlZones; ++HumidControlledZoneNum) { - auto &humidityControlZone = state.dataZoneCtrls->HumidityControlZone(HumidControlledZoneNum); - if (humidityControlZone.ActualZoneNum != ZoneNum) continue; - ZoneAirRH = PsyRhFnTdbWPb(state, MAT, zoneAirHumRat, state.dataEnvrn->OutBaroPress) * 100.0; - ZoneRHHumidifyingSetPoint = GetCurrentScheduleValue(state, humidityControlZone.HumidifyingSchedIndex); - ZoneRHDehumidifyingSetPoint = GetCurrentScheduleValue(state, humidityControlZone.DehumidifyingSchedIndex); - - // Apply EMS values to overwrite the humidistat values - if (humidityControlZone.EMSOverrideHumidifySetPointOn) { - ZoneRHHumidifyingSetPoint = humidityControlZone.EMSOverrideHumidifySetPointValue; - } - if (humidityControlZone.EMSOverrideDehumidifySetPointOn) { - ZoneRHDehumidifyingSetPoint = humidityControlZone.EMSOverrideDehumidifySetPointValue; + if (humidityControlZone.EMSOverrideDehumidifySetPointOn) { + ZoneRHDehumidifyingSetPoint = humidityControlZone.EMSOverrideDehumidifySetPointValue; } // Apply offsets for faulty humidistats @@ -4675,13 +3868,13 @@ void CalcPredictedHumidityRatio(EnergyPlusData &state, int const ZoneNum, Real64 IsThermostatFound = true; // Check fault availability schedules - if (GetCurrentScheduleValue(state, state.dataFaultsMgr->FaultsThermostatOffset(iFaultThermo).AvaiSchedPtr) > - 0.0) { + if (ScheduleManager::GetCurrentScheduleValue( + state, state.dataFaultsMgr->FaultsThermostatOffset(iFaultThermo).AvaiSchedPtr) > 0.0) { // Check fault severity schedules to update the reference thermostat offset double rSchVal = 1.0; if (state.dataFaultsMgr->FaultsThermostatOffset(iFaultThermo).SeveritySchedPtr >= 0) { - rSchVal = GetCurrentScheduleValue( + rSchVal = ScheduleManager::GetCurrentScheduleValue( state, state.dataFaultsMgr->FaultsThermostatOffset(iFaultThermo).SeveritySchedPtr); } offsetThermostat = rSchVal * state.dataFaultsMgr->FaultsThermostatOffset(iFaultThermo).Offset; @@ -4704,16 +3897,17 @@ void CalcPredictedHumidityRatio(EnergyPlusData &state, int const ZoneNum, Real64 if (offsetThermostat != 0.0) { // Calculate the humidistat offset value from the thermostat offset value - faultZoneWHumidifyingSetPoint = - PsyWFnTdbRhPb(state, (MAT + offsetThermostat), (ZoneRHHumidifyingSetPoint / 100.0), state.dataEnvrn->OutBaroPress); - faultZoneWDehumidifyingSetPoint = - PsyWFnTdbRhPb(state, (MAT + offsetThermostat), (ZoneRHDehumidifyingSetPoint / 100.0), state.dataEnvrn->OutBaroPress); + faultZoneWHumidifyingSetPoint = Psychrometrics::PsyWFnTdbRhPb( + state, (this->MAT + offsetThermostat), (ZoneRHHumidifyingSetPoint / 100.0), state.dataEnvrn->OutBaroPress); + faultZoneWDehumidifyingSetPoint = Psychrometrics::PsyWFnTdbRhPb( + state, (this->MAT + offsetThermostat), (ZoneRHDehumidifyingSetPoint / 100.0), state.dataEnvrn->OutBaroPress); offsetZoneRHHumidifyingSetPoint = ZoneRHHumidifyingSetPoint - - PsyRhFnTdbWPb(state, MAT, faultZoneWHumidifyingSetPoint, state.dataEnvrn->OutBaroPress) * 100.0; + Psychrometrics::PsyRhFnTdbWPb(state, this->MAT, faultZoneWHumidifyingSetPoint, state.dataEnvrn->OutBaroPress) * 100.0; offsetZoneRHDehumidifyingSetPoint = ZoneRHDehumidifyingSetPoint - - PsyRhFnTdbWPb(state, MAT, faultZoneWDehumidifyingSetPoint, state.dataEnvrn->OutBaroPress) * 100.0; + Psychrometrics::PsyRhFnTdbWPb(state, this->MAT, faultZoneWDehumidifyingSetPoint, state.dataEnvrn->OutBaroPress) * + 100.0; // Apply the calculated humidistat offset value // Positive offset means the sensor reading is higher than the actual value @@ -4729,13 +3923,14 @@ void CalcPredictedHumidityRatio(EnergyPlusData &state, int const ZoneNum, Real64 // For Humidistat Offset Type II: ThermostatOffsetIndependent // Check fault availability schedules - if (GetCurrentScheduleValue(state, state.dataFaultsMgr->FaultsHumidistatOffset(iFault).AvaiSchedPtr) > 0.0) { + if (ScheduleManager::GetCurrentScheduleValue(state, state.dataFaultsMgr->FaultsHumidistatOffset(iFault).AvaiSchedPtr) > 0.0) { // Check fault severity schedules to update the reference humidistat offset double rSchVal = 1.0; double offsetUpdated; if (state.dataFaultsMgr->FaultsHumidistatOffset(iFault).SeveritySchedPtr >= 0) { - rSchVal = GetCurrentScheduleValue(state, state.dataFaultsMgr->FaultsHumidistatOffset(iFault).SeveritySchedPtr); + rSchVal = ScheduleManager::GetCurrentScheduleValue( + state, state.dataFaultsMgr->FaultsHumidistatOffset(iFault).SeveritySchedPtr); } offsetUpdated = rSchVal * state.dataFaultsMgr->FaultsHumidistatOffset(iFault).Offset; @@ -4771,7 +3966,6 @@ void CalcPredictedHumidityRatio(EnergyPlusData &state, int const ZoneNum, Real64 if (ZoneRHHumidifyingSetPoint == ZoneRHDehumidifyingSetPoint) SingleSetPoint = true; ControlledHumidZoneFlag = true; - break; } // HumidControlledZoneNum // if zone latent sizing is requested but no humidistat exists @@ -4787,10 +3981,10 @@ void CalcPredictedHumidityRatio(EnergyPlusData &state, int const ZoneNum, Real64 auto &zoneSizingInput = state.dataSize->ZoneSizingInput(ZoneSizNum); if (zoneSizingInput.zoneLatentSizing) { ZoneRHDehumidifyingSetPoint = (zoneSizingInput.zoneRHDehumidifySchIndex) - ? GetCurrentScheduleValue(state, zoneSizingInput.zoneRHDehumidifySchIndex) + ? ScheduleManager::GetCurrentScheduleValue(state, zoneSizingInput.zoneRHDehumidifySchIndex) : zoneSizingInput.zoneRHDehumidifySetPoint; ZoneRHHumidifyingSetPoint = (zoneSizingInput.zoneRHHumidifySchIndex) - ? GetCurrentScheduleValue(state, zoneSizingInput.zoneRHHumidifySchIndex) + ? ScheduleManager::GetCurrentScheduleValue(state, zoneSizingInput.zoneRHHumidifySchIndex) : zoneSizingInput.zoneRHHumidifySetPoint; if (ZoneRHHumidifyingSetPoint > ZoneRHDehumidifyingSetPoint) ZoneRHHumidifyingSetPoint = ZoneRHDehumidifyingSetPoint; if (ZoneRHHumidifyingSetPoint == ZoneRHDehumidifyingSetPoint) SingleSetPoint = true; @@ -4801,13 +3995,17 @@ void CalcPredictedHumidityRatio(EnergyPlusData &state, int const ZoneNum, Real64 } } + Real64 LoadToHumidifySetPoint = 0.0; // Moisture load at humidifying set point + Real64 LoadToDehumidifySetPoint = 0.0; // Moisture load at dehumidifying set point + Real64 totalOutputRequired = 0.0; if (ControlledHumidZoneFlag) { + // Calculate hourly humidity ratio from infiltration + humidity added from latent load // to determine system added/subtracted moisture. - LatentGain = state.dataHeatBalFanSys->ZoneLatentGain(ZoneNum) + state.dataHeatBalFanSys->SumLatentHTRadSys(ZoneNum) + - state.dataHeatBalFanSys->SumLatentPool(ZoneNum); + Real64 LatentGain = + this->ZoneLatentGain + state.dataHeatBalFanSys->SumLatentHTRadSys(zoneNum) + state.dataHeatBalFanSys->SumLatentPool(zoneNum); - SysTimeStepInSeconds = DataGlobalConstants::SecInHour * state.dataHVACGlobal->TimeStepSys; + Real64 SysTimeStepInSeconds = DataGlobalConstants::SecInHour * state.dataHVACGlobal->TimeStepSys; // Calculate the coefficients for the 3rd Order derivative for final // zone humidity ratio. The A, B, C coefficients are analogous to the heat balance. @@ -4815,37 +4013,40 @@ void CalcPredictedHumidityRatio(EnergyPlusData &state, int const ZoneNum, Real64 // are currently set to zero when the CTF only version is used. // The density of air and latent heat of vaporization are calculated as functions. - RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, ZT, zoneAirHumRat, RoutineName); - H2OHtOfVap = PsyHgAirFnWTdb(zoneAirHumRat, ZT); + Real64 RhoAir = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, this->ZT, this->ZoneAirHumRat, RoutineName); + Real64 H2OHtOfVap = Psychrometrics::PsyHgAirFnWTdb(this->ZoneAirHumRat, this->ZT); // Assume that the system will have flow + Real64 A = 0.0; + Real64 B = 0.0; + Real64 C = 0.0; if (state.afn->multizone_always_simulated || (state.afn->simulation_control.type == AirflowNetwork::ControlType::MultizoneWithDistributionOnlyDuringFanOperation && state.afn->AirflowNetworkFanActivated)) { // Multizone airflow calculated in AirflowNetwork - B = (LatentGain / H2OHtOfVap) + state.afn->exchangeData(ZoneNum).SumMHrW + state.afn->exchangeData(ZoneNum).SumMMHrW + - state.dataHeatBalFanSys->SumHmARaW(ZoneNum); - A = state.afn->exchangeData(ZoneNum).SumMHr + state.afn->exchangeData(ZoneNum).SumMMHr + state.dataHeatBalFanSys->SumHmARa(ZoneNum); + B = (LatentGain / H2OHtOfVap) + state.afn->exchangeData(zoneNum).SumMHrW + state.afn->exchangeData(zoneNum).SumMMHrW + this->SumHmARaW; + A = state.afn->exchangeData(zoneNum).SumMHr + state.afn->exchangeData(zoneNum).SumMMHr + this->SumHmARa; } else { - B = (LatentGain / H2OHtOfVap) + - ((state.dataHeatBalFanSys->OAMFL(ZoneNum) + state.dataHeatBalFanSys->VAMFL(ZoneNum) + state.dataHeatBalFanSys->CTMFL(ZoneNum)) * - state.dataEnvrn->OutHumRat) + - state.dataHeatBalFanSys->EAMFLxHumRat(ZoneNum) + state.dataHeatBalFanSys->SumHmARaW(ZoneNum) + - state.dataHeatBalFanSys->MixingMassFlowXHumRat(ZoneNum) + state.dataHeatBalFanSys->MDotOA(ZoneNum) * state.dataEnvrn->OutHumRat; - A = state.dataHeatBalFanSys->OAMFL(ZoneNum) + state.dataHeatBalFanSys->VAMFL(ZoneNum) + state.dataHeatBalFanSys->EAMFL(ZoneNum) + - state.dataHeatBalFanSys->CTMFL(ZoneNum) + state.dataHeatBalFanSys->SumHmARa(ZoneNum) + - state.dataHeatBalFanSys->MixingMassFlowZone(ZoneNum) + state.dataHeatBalFanSys->MDotOA(ZoneNum); - } - C = RhoAir * zone.Volume * zone.ZoneVolCapMultpMoist / SysTimeStepInSeconds; - - if (state.dataRoomAirMod->AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { - auto &roomAFNInfo = state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum); - RoomAirNode = roomAFNInfo.ControlAirNodeID; - H2OHtOfVap = PsyHgAirFnWTdb(roomAFNInfo.Node(RoomAirNode).HumRat, roomAFNInfo.Node(RoomAirNode).AirTemp); + B = (LatentGain / H2OHtOfVap) + ((this->OAMFL + this->VAMFL + this->CTMFL) * state.dataEnvrn->OutHumRat) + this->EAMFLxHumRat + + this->SumHmARaW + this->MixingMassFlowXHumRat + this->MDotOA * state.dataEnvrn->OutHumRat; + A = this->OAMFL + this->VAMFL + this->EAMFL + this->CTMFL + this->SumHmARa + this->MixingMassFlowZone + this->MDotOA; + } + Real64 volume = 0.0; + if (spaceNum > 0) { + volume = state.dataHeatBal->space(spaceNum).Volume; + } else { + volume = thisZone.Volume; + } + C = RhoAir * volume * thisZone.ZoneVolCapMultpMoist / SysTimeStepInSeconds; + + if (state.dataRoomAirMod->AirModel(zoneNum).AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { + auto &roomAFNInfo = state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(zoneNum); + int RoomAirNode = roomAFNInfo.ControlAirNodeID; + H2OHtOfVap = Psychrometrics::PsyHgAirFnWTdb(roomAFNInfo.Node(RoomAirNode).HumRat, roomAFNInfo.Node(RoomAirNode).AirTemp); A = roomAFNInfo.Node(RoomAirNode).SumLinkM + roomAFNInfo.Node(RoomAirNode).SumHmARa; B = (roomAFNInfo.Node(RoomAirNode).SumIntLatentGain / H2OHtOfVap) + roomAFNInfo.Node(RoomAirNode).SumLinkMW + roomAFNInfo.Node(RoomAirNode).SumHmARaW; - C = roomAFNInfo.Node(RoomAirNode).RhoAir * roomAFNInfo.Node(RoomAirNode).AirVolume * zone.ZoneVolCapMultpMoist / + C = roomAFNInfo.Node(RoomAirNode).RhoAir * roomAFNInfo.Node(RoomAirNode).AirVolume * thisZone.ZoneVolCapMultpMoist / (DataGlobalConstants::SecInHour * state.dataHVACGlobal->TimeStepSys); } @@ -4854,64 +4055,60 @@ void CalcPredictedHumidityRatio(EnergyPlusData &state, int const ZoneNum, Real64 // this amount of moisture must be added to the zone to reach the setpoint. Negative values represent // the amount of moisture that must be removed by the system. // MoistLoadHumidSetPoint = massflow * HumRat = kgDryAir/s * kgWater/kgDryAir = kgWater/s - WZoneSetPoint = PsyWFnTdbRhPb(state, ZT, (ZoneRHHumidifyingSetPoint / 100.0), state.dataEnvrn->OutBaroPress, RoutineName); + Real64 WZoneSetPoint = + Psychrometrics::PsyWFnTdbRhPb(state, this->ZT, (ZoneRHHumidifyingSetPoint / 100.0), state.dataEnvrn->OutBaroPress, RoutineName); Real64 exp_700_A_C(0.0); if (state.dataHeatBal->ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::ThirdOrder) { LoadToHumidifySetPoint = - ((11.0 / 6.0) * C + A) * WZoneSetPoint - (B + C * (3.0 * state.dataHeatBalFanSys->WZoneTimeMinus1Temp(ZoneNum) - - (3.0 / 2.0) * state.dataHeatBalFanSys->WZoneTimeMinus2Temp(ZoneNum) + - (1.0 / 3.0) * state.dataHeatBalFanSys->WZoneTimeMinus3Temp(ZoneNum))); + ((11.0 / 6.0) * C + A) * WZoneSetPoint - + (B + C * (3.0 * this->WPrevZoneTSTemp[0] - (3.0 / 2.0) * this->WPrevZoneTSTemp[1] + (1.0 / 3.0) * this->WPrevZoneTSTemp[2])); // Exact solution } else if (state.dataHeatBal->ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::AnalyticalSolution) { if (A == 0.0) { // B=0 - LoadToHumidifySetPoint = C * (WZoneSetPoint - state.dataHeatBalFanSys->ZoneW1(ZoneNum)) - B; + LoadToHumidifySetPoint = C * (WZoneSetPoint - this->ZoneW1) - B; } else { exp_700_A_C = std::exp(min(700.0, -A / C)); // Tuned Save expensive value - LoadToHumidifySetPoint = A * (WZoneSetPoint - state.dataHeatBalFanSys->ZoneW1(ZoneNum) * exp_700_A_C) / (1.0 - exp_700_A_C) - B; + LoadToHumidifySetPoint = A * (WZoneSetPoint - this->ZoneW1 * exp_700_A_C) / (1.0 - exp_700_A_C) - B; } } else if (state.dataHeatBal->ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::EulerMethod) { - LoadToHumidifySetPoint = C * (WZoneSetPoint - state.dataHeatBalFanSys->ZoneW1(ZoneNum)) + A * WZoneSetPoint - B; + LoadToHumidifySetPoint = C * (WZoneSetPoint - this->ZoneW1) + A * WZoneSetPoint - B; } if (RAFNFrac > 0.0) LoadToHumidifySetPoint = LoadToHumidifySetPoint / RAFNFrac; - zoneSysMoistureDemand.OutputRequiredToHumidifyingSP = LoadToHumidifySetPoint; - WZoneSetPoint = PsyWFnTdbRhPb(state, ZT, (ZoneRHDehumidifyingSetPoint / 100.0), state.dataEnvrn->OutBaroPress, RoutineName); + WZoneSetPoint = + Psychrometrics::PsyWFnTdbRhPb(state, this->ZT, (ZoneRHDehumidifyingSetPoint / 100.0), state.dataEnvrn->OutBaroPress, RoutineName); if (state.dataHeatBal->ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::ThirdOrder) { LoadToDehumidifySetPoint = - ((11.0 / 6.0) * C + A) * WZoneSetPoint - (B + C * (3.0 * state.dataHeatBalFanSys->WZoneTimeMinus1Temp(ZoneNum) - - (3.0 / 2.0) * state.dataHeatBalFanSys->WZoneTimeMinus2Temp(ZoneNum) + - (1.0 / 3.0) * state.dataHeatBalFanSys->WZoneTimeMinus3Temp(ZoneNum))); + ((11.0 / 6.0) * C + A) * WZoneSetPoint - + (B + C * (3.0 * this->WPrevZoneTSTemp[0] - (3.0 / 2.0) * this->WPrevZoneTSTemp[1] + (1.0 / 3.0) * this->WPrevZoneTSTemp[2])); // Exact solution } else if (state.dataHeatBal->ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::AnalyticalSolution) { if (A == 0.0) { // B=0 - LoadToDehumidifySetPoint = C * (WZoneSetPoint - state.dataHeatBalFanSys->ZoneW1(ZoneNum)) - B; + LoadToDehumidifySetPoint = C * (WZoneSetPoint - this->ZoneW1) - B; } else { - LoadToDehumidifySetPoint = - A * (WZoneSetPoint - state.dataHeatBalFanSys->ZoneW1(ZoneNum) * exp_700_A_C) / (1.0 - exp_700_A_C) - B; // exp_700_A_C set above + LoadToDehumidifySetPoint = A * (WZoneSetPoint - this->ZoneW1 * exp_700_A_C) / (1.0 - exp_700_A_C) - B; // exp_700_A_C set above } } else if (state.dataHeatBal->ZoneAirSolutionAlgo == DataHeatBalance::SolutionAlgo::EulerMethod) { - LoadToDehumidifySetPoint = C * (WZoneSetPoint - state.dataHeatBalFanSys->ZoneW1(ZoneNum)) + A * WZoneSetPoint - B; + LoadToDehumidifySetPoint = C * (WZoneSetPoint - this->ZoneW1) + A * WZoneSetPoint - B; } if (RAFNFrac > 0.0) LoadToDehumidifySetPoint = LoadToDehumidifySetPoint / RAFNFrac; - zoneSysMoistureDemand.OutputRequiredToDehumidifyingSP = LoadToDehumidifySetPoint; // The load is added to the TotalOutputRequired as in the Temperature Predictor. There is also the remaining // output variable for those who will use this for humidity control and stored in DataZoneEnergyDemands with the // analogous temperature terms. + if (SingleSetPoint) { - zoneSysMoistureDemand.TotalOutputRequired = LoadToHumidifySetPoint; + totalOutputRequired = LoadToHumidifySetPoint; } else { if (LoadToHumidifySetPoint > 0.0 && LoadToDehumidifySetPoint > 0.0) { - zoneSysMoistureDemand.TotalOutputRequired = LoadToHumidifySetPoint; - RHSetPoint = ZoneRHHumidifyingSetPoint; + totalOutputRequired = LoadToHumidifySetPoint; } else if (LoadToHumidifySetPoint < 0.0 && LoadToDehumidifySetPoint < 0.0) { - zoneSysMoistureDemand.TotalOutputRequired = LoadToDehumidifySetPoint; - RHSetPoint = ZoneRHDehumidifyingSetPoint; + totalOutputRequired = LoadToDehumidifySetPoint; } else if (LoadToHumidifySetPoint <= 0.0 && LoadToDehumidifySetPoint >= 0.0) { // deadband includes zero loads - zoneSysMoistureDemand.TotalOutputRequired = 0.0; + totalOutputRequired = 0.0; } else { // this should never occur! ShowSevereError( state, "Humidistat: Unanticipated combination of humidifying and dehumidifying loads - report to EnergyPlus Development Team"); - ShowContinueErrorTimeStamp(state, format("occurs in Zone = {}", zone.Name)); + ShowContinueErrorTimeStamp(state, format("occurs in Zone = {}", thisZone.Name)); ShowContinueError( state, format("LoadToHumidifySetPoint={:.5R}, LoadToDehumidifySetPoint={:.5R}", LoadToHumidifySetPoint, LoadToDehumidifySetPoint)); @@ -4922,54 +4119,58 @@ void CalcPredictedHumidityRatio(EnergyPlusData &state, int const ZoneNum, Real64 } } - // Apply zone multipliers as needed - ReportMoistLoadsZoneMultiplier(zoneSysMoistureDemand.TotalOutputRequired, - zoneSysMoistureDemand.OutputRequiredToHumidifyingSP, - zoneSysMoistureDemand.OutputRequiredToDehumidifyingSP, - state.dataHeatBal->latentReports(ZoneNum).ZoneMoisturePredictedRate, - state.dataHeatBal->latentReports(ZoneNum).ZoneMoisturePredictedHumSPRate, - state.dataHeatBal->latentReports(ZoneNum).ZoneMoisturePredictedDehumSPRate, - zone.Multiplier, - zone.ListMultiplier); - - // init each sequenced demand to the full output - if (allocated(zoneSysMoistureDemand.SequencedOutputRequired)) - zoneSysMoistureDemand.SequencedOutputRequired = zoneSysMoistureDemand.TotalOutputRequired; - if (allocated(zoneSysMoistureDemand.SequencedOutputRequiredToHumidSP)) - zoneSysMoistureDemand.SequencedOutputRequiredToHumidSP = zoneSysMoistureDemand.OutputRequiredToHumidifyingSP; - if (allocated(zoneSysMoistureDemand.SequencedOutputRequiredToDehumidSP)) - zoneSysMoistureDemand.SequencedOutputRequiredToDehumidSP = zoneSysMoistureDemand.OutputRequiredToDehumidifyingSP; + // Apply zone multipliers as needed or set to zero + if (spaceNum > 0) { + auto &thisspaceSysMoistureDemand = state.dataZoneEnergyDemand->spaceSysMoistureDemand(spaceNum); + if (ControlledHumidZoneFlag) { + thisspaceSysMoistureDemand.reportMoistLoadsZoneMultiplier( + state, zoneNum, totalOutputRequired, LoadToHumidifySetPoint, LoadToDehumidifySetPoint); + } else { + thisspaceSysMoistureDemand.TotalOutputRequired = 0.0; + thisspaceSysMoistureDemand.OutputRequiredToDehumidifyingSP = 0.0; + thisspaceSysMoistureDemand.OutputRequiredToHumidifyingSP = 0.0; + } + } else { + auto &thisZoneSysMoistureDemand = state.dataZoneEnergyDemand->ZoneSysMoistureDemand(zoneNum); + if (ControlledHumidZoneFlag) { + thisZoneSysMoistureDemand.reportMoistLoadsZoneMultiplier( + state, zoneNum, totalOutputRequired, LoadToHumidifySetPoint, LoadToDehumidifySetPoint); + } else { + thisZoneSysMoistureDemand.TotalOutputRequired = 0.0; + thisZoneSysMoistureDemand.OutputRequiredToDehumidifyingSP = 0.0; + thisZoneSysMoistureDemand.OutputRequiredToHumidifyingSP = 0.0; + } + } } -void ReportMoistLoadsZoneMultiplier(Real64 &TotalLoad, - Real64 &TotalHumidLoad, - Real64 &TotalDehumidLoad, - Real64 &MoistLoadSingleZone, - Real64 &MoistLoadHumidSingleZone, - Real64 &MoistLoadDehumidSingleZone, - Real64 const ZoneMultiplier, - Real64 const ZoneMultiplierList) +Real64 correctZoneAirTemps(EnergyPlusData &state, + bool useZoneTimeStepHistory // if true then use zone timestep history, if false use system time step history +) { - MoistLoadSingleZone = TotalLoad; - MoistLoadHumidSingleZone = TotalHumidLoad; - MoistLoadDehumidSingleZone = TotalDehumidLoad; - - Real64 ZoneMultFac = ZoneMultiplier * ZoneMultiplierList; - - TotalLoad *= ZoneMultFac; - TotalHumidLoad *= ZoneMultFac; - TotalDehumidLoad *= ZoneMultFac; + Real64 maxTempChange = DataPrecisionGlobals::constant_zero; // Max absolute air temperature change between previous and current timestep + for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { + Real64 zoneTempChange = state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum).correctAirTemp(state, useZoneTimeStepHistory, zoneNum); + if (state.dataHeatBal->doSpaceHeatBalance) { + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + Real64 spaceTempChange = + state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).correctAirTemp(state, useZoneTimeStepHistory, zoneNum, spaceNum); + maxTempChange = max(maxTempChange, spaceTempChange); + } + } + maxTempChange = max(maxTempChange, zoneTempChange); + } + return maxTempChange; } -void CorrectZoneAirTemp(EnergyPlusData &state, - Real64 &ZoneTempChange, // Temperature change in zone air between previous and current timestep - bool const UseZoneTimeStepHistory // if true then use zone timestep history, if false use system time step history -) +Real64 ZoneSpaceHeatBalanceData::correctAirTemp( + EnergyPlusData &state, + bool const useZoneTimeStepHistory, // if true then use zone timestep history, if false use system time step history + int const zoneNum, + int const spaceNum) { // SUBROUTINE INFORMATION: // AUTHOR Russell Taylor - // DATE WRITTEN ??? // MODIFIED November 1999, LKL; November 2016 Sang Hoon Lee, Tianzhen Hong, Rongpeng Zhang; // RE-ENGINEERED July 2003 (Peter Graham Ellis) // February 2008 (Brent Griffith reworked history ) @@ -4978,332 +4179,302 @@ void CorrectZoneAirTemp(EnergyPlusData &state, // This subroutine updates the zone air temperature and modifies the system // time step. - using InternalHeatGains::SumAllInternalConvectionGainsExceptPeople; - using RoomAirModelManager::ManageAirModel; - using ScheduleManager::GetCurrentScheduleValue; - using ScheduleManager::GetScheduleMaxValue; - using ScheduleManager::GetScheduleMinValue; + static constexpr std::string_view RoutineName("correctAirTemp"); - // SUBROUTINE PARAMETER DEFINITIONS: - static constexpr std::string_view RoutineName("CorrectZoneAirTemp"); + Real64 tempChange = DataPrecisionGlobals::constant_zero; // Zone or space air temperature change between previous and current timestep - // SUBROUTINE LOCAL VARIABLE DECLARATIONS: - Real64 CpAir; // specific heat of air - Real64 SumIntGain(0.0); // Zone sum of convective internal gains - Real64 SumIntGainExceptPeople(0.0); // Zone sum of convective internal gains except for convective heat from people, HybridModel - Real64 SumHA(0.0); // Zone sum of Hc*Area - Real64 SumHATsurf(0.0); // Zone sum of Hc*Area*Tsurf - Real64 SumHATref(0.0); // Zone sum of Hc*Area*Tref, for ceiling diffuser convection correlation - Real64 SumMCp(0.0); // Zone sum of MassFlowRate*Cp - Real64 SumMCpT(0.0); // Zone sum of MassFlowRate*Cp*T - Real64 SumSysMCp(0.0); // Zone sum of air system MassFlowRate*Cp - Real64 SumSysMCpT(0.0); // Zone sum of air system MassFlowRate*Cp*T - Real64 ZoneEnthalpyIn(0.0); // Zone inlet air enthalpy - Real64 TempDepCoef(0.0); // Formerly CoefSumha, coef in zone temp equation with dimensions of h*A - Real64 TempIndCoef(0.0); // Formerly CoefSumhat, coef in zone temp equation with dimensions of h*A(T1 - Real64 AirCap(0.0); // Formerly CoefAirrat, coef in zone temp eqn with dim of "air power capacity" - Real64 SNLoad(0.0); // Sensible load calculated for zone in watts and then loaded in report variables - int ZoneNum(0); - int ZoneNodeNum(0); // System node number for air flow through zone either by system or as a plenum - - Real64 TempSupplyAir; - Real64 ZoneMult; - - // Initializations - ZoneTempChange = DataPrecisionGlobals::constant_zero; - - auto &TimeStepSys = state.dataHVACGlobal->TimeStepSys; - auto &Zone = state.dataHeatBal->Zone; - auto &RoomAirflowNetworkZoneInfo = state.dataRoomAirMod->RoomAirflowNetworkZoneInfo; - auto &ZT = state.dataHeatBalFanSys->ZT; - auto &MAT = state.dataHeatBalFanSys->MAT; - auto &ZoneT1 = state.dataHeatBalFanSys->ZoneT1; - auto &Node = state.dataLoopNodes->Node; - auto &ZoneAirHumRat = state.dataHeatBalFanSys->ZoneAirHumRat; - auto &ZoneAirSolutionAlgo = state.dataHeatBal->ZoneAirSolutionAlgo; - auto &AirModel = state.dataRoomAirMod->AirModel; - auto &AIRRAT = state.dataHeatBalFanSys->AIRRAT; + assert(zoneNum > 0); + auto &thisZone = state.dataHeatBal->Zone(zoneNum); // Update zone temperatures - for (ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { - - ZoneMult = Zone(ZoneNum).Multiplier * Zone(ZoneNum).ListMultiplier; - // update the variables actually used in the balance equations. - if (!UseZoneTimeStepHistory) { - state.dataHeatBalFanSys->ZTM1(ZoneNum) = state.dataHeatBalFanSys->DSXMAT(ZoneNum); - state.dataHeatBalFanSys->ZTM2(ZoneNum) = state.dataHeatBalFanSys->DSXM2T(ZoneNum); - state.dataHeatBalFanSys->ZTM3(ZoneNum) = state.dataHeatBalFanSys->DSXM3T(ZoneNum); + Real64 ZoneMult = thisZone.Multiplier * thisZone.ListMultiplier; - state.dataHeatBalFanSys->WZoneTimeMinus1Temp(ZoneNum) = state.dataHeatBalFanSys->DSWZoneTimeMinus1(ZoneNum); - state.dataHeatBalFanSys->WZoneTimeMinus2Temp(ZoneNum) = state.dataHeatBalFanSys->DSWZoneTimeMinus2(ZoneNum); - state.dataHeatBalFanSys->WZoneTimeMinus3Temp(ZoneNum) = state.dataHeatBalFanSys->DSWZoneTimeMinus3(ZoneNum); - } else { - state.dataHeatBalFanSys->ZTM1(ZoneNum) = state.dataHeatBalFanSys->XMAT(ZoneNum); - state.dataHeatBalFanSys->ZTM2(ZoneNum) = state.dataHeatBalFanSys->XM2T(ZoneNum); - state.dataHeatBalFanSys->ZTM3(ZoneNum) = state.dataHeatBalFanSys->XM3T(ZoneNum); - - state.dataHeatBalFanSys->WZoneTimeMinus1Temp(ZoneNum) = state.dataHeatBalFanSys->WZoneTimeMinus1(ZoneNum); - state.dataHeatBalFanSys->WZoneTimeMinus2Temp(ZoneNum) = state.dataHeatBalFanSys->WZoneTimeMinus2(ZoneNum); - state.dataHeatBalFanSys->WZoneTimeMinus3Temp(ZoneNum) = state.dataHeatBalFanSys->WZoneTimeMinus3(ZoneNum); - } + // update the variables actually used in the balance equations. + if (!useZoneTimeStepHistory) { + this->ZTM = this->DSXMAT; + this->WPrevZoneTSTemp = this->DSWPrevZoneTS; + } else { + this->ZTM = this->XMAT; + this->WPrevZoneTSTemp = this->WPrevZoneTS; + } - AIRRAT(ZoneNum) = Zone(ZoneNum).Volume * Zone(ZoneNum).ZoneVolCapMultpSens * - PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, MAT(ZoneNum), ZoneAirHumRat(ZoneNum), RoutineName) * - PsyCpAirFnW(ZoneAirHumRat(ZoneNum)) / (TimeStepSys * DataGlobalConstants::SecInHour); + Real64 volume = 0.0; + if (spaceNum > 0) { + volume = state.dataHeatBal->space(spaceNum).Volume; + } else { + volume = thisZone.Volume; + } + this->AirPowerCap = volume * thisZone.ZoneVolCapMultpSens * + Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, this->MAT, this->ZoneAirHumRat, RoutineName) * + Psychrometrics::PsyCpAirFnW(this->ZoneAirHumRat) / (state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour); - AirCap = AIRRAT(ZoneNum); + // SpaceHB TODO: For now, room air model is only for zones + if (spaceNum == 0) { + RoomAirModelManager::ManageAirModel(state, zoneNum); + } - ManageAirModel(state, ZoneNum); + // Calculate the various heat balance sums + this->calcZoneOrSpaceSums(state, true, zoneNum, spaceNum); - // Calculate the various heat balance sums - CalcZoneSums(state, ZoneNum, SumIntGain, SumHA, SumHATsurf, SumHATref, SumMCp, SumMCpT, SumSysMCp, SumSysMCpT); + // Sum all convective internal gains except for people: SumIntGainExceptPeople + if (state.dataHybridModel->FlagHybridModel_PC) { + // TODO: For now, don't do space heat balance with hybrid model + this->SumIntGainExceptPeople = InternalHeatGains::SumAllInternalConvectionGainsExceptPeople(state, zoneNum); + } - // Sum all convective internal gains except for people: SumIntGainExceptPeople - if (state.dataHybridModel->FlagHybridModel_PC) { - SumIntGainExceptPeople = SumAllInternalConvectionGainsExceptPeople(state, ZoneNum); - } + // ZoneTempHistoryTerm = (3.0D0 * ZTM1(zoneNum) - (3.0D0/2.0D0) * ZTM2(zoneNum) + (1.0D0/3.0D0) * ZTM3(zoneNum)) + int ZoneNodeNum = thisZone.SystemZoneNodeNumber; + if (spaceNum > 0) { + ZoneNodeNum = state.dataHeatBal->space(spaceNum).SystemZoneNodeNumber; + } - // ZoneTempHistoryTerm = (3.0D0 * ZTM1(ZoneNum) - (3.0D0/2.0D0) * ZTM2(ZoneNum) + (1.0D0/3.0D0) * ZTM3(ZoneNum)) - ZoneNodeNum = Zone(ZoneNum).SystemZoneNodeNumber; + Real64 SNLoad = 0.0; - SNLoad = 0.0; + if (ZoneNodeNum > 0) { // This zone is controlled by a zone equipment configuration or zone plenum + auto &thisSystemNode = state.dataLoopNodes->Node(ZoneNodeNum); - if (ZoneNodeNum > 0) { // This zone is controlled by a zone equipment configuration or zone plenum + // Heat balance coefficients for controlled zone, i.e. with system air flow + this->TempDepCoef = this->SumHA + this->SumMCp + this->SumSysMCp; + this->TempIndCoef = this->SumIntGain + this->SumHATsurf - this->SumHATref + this->SumMCpT + this->SumSysMCpT + + (this->NonAirSystemResponse / ZoneMult + this->SysDepZoneLoadsLagged); - // Heat balance coefficients for controlled zone, i.e. with system air flow - TempDepCoef = SumHA + SumMCp + SumSysMCp; - TempIndCoef = - SumIntGain + SumHATsurf - SumHATref + SumMCpT + SumSysMCpT + - (state.dataHeatBalFanSys->NonAirSystemResponse(ZoneNum) / ZoneMult + state.dataHeatBalFanSys->SysDepZoneLoadsLagged(ZoneNum)); - // TempHistoryTerm = AirCap * (3.0 * ZTM1(ZoneNum) - (3.0/2.0) * ZTM2(ZoneNum) + (1.0/3.0) * ZTM3(ZoneNum)) !debug only + if (state.afn->distribution_simulated) { + this->TempIndCoef += state.afn->exchangeData(zoneNum).TotalSen; + } - if (state.afn->distribution_simulated) { - TempIndCoef += state.afn->exchangeData(ZoneNum).TotalSen; + // Solve for zone air temperature + switch (state.dataHeatBal->ZoneAirSolutionAlgo) { + case DataHeatBalance::SolutionAlgo::ThirdOrder: { + this->ZT = (this->TempIndCoef + this->AirPowerCap * (3.0 * this->ZTM[0] - (3.0 / 2.0) * this->ZTM[1] + (1.0 / 3.0) * this->ZTM[2])) / + ((11.0 / 6.0) * this->AirPowerCap + this->TempDepCoef); + } break; + case DataHeatBalance::SolutionAlgo::AnalyticalSolution: { + if (this->TempDepCoef == 0.0) { // B=0 + this->ZT = this->ZoneT1 + this->TempIndCoef / this->AirPowerCap; + } else { + this->ZT = (this->ZoneT1 - this->TempIndCoef / this->TempDepCoef) * std::exp(min(700.0, -this->TempDepCoef / this->AirPowerCap)) + + this->TempIndCoef / this->TempDepCoef; } - // TempDepZnLd(ZoneNum) = (11.0/6.0) * AirCap + TempDepCoef - // TempIndZnLd(ZoneNum) = TempHistoryTerm + TempIndCoef - // Solve for zone air temperature - switch (ZoneAirSolutionAlgo) { - case DataHeatBalance::SolutionAlgo::ThirdOrder: { - ZT(ZoneNum) = - (TempIndCoef + AirCap * (3.0 * state.dataHeatBalFanSys->ZTM1(ZoneNum) - (3.0 / 2.0) * state.dataHeatBalFanSys->ZTM2(ZoneNum) + - (1.0 / 3.0) * state.dataHeatBalFanSys->ZTM3(ZoneNum))) / - ((11.0 / 6.0) * AirCap + TempDepCoef); - // Exact solution - } break; - case DataHeatBalance::SolutionAlgo::AnalyticalSolution: { - if (TempDepCoef == 0.0) { // B=0 - ZT(ZoneNum) = ZoneT1(ZoneNum) + TempIndCoef / AirCap; - } else { - ZT(ZoneNum) = - (ZoneT1(ZoneNum) - TempIndCoef / TempDepCoef) * std::exp(min(700.0, -TempDepCoef / AirCap)) + TempIndCoef / TempDepCoef; - } - } break; - case DataHeatBalance::SolutionAlgo::EulerMethod: { - ZT(ZoneNum) = (AirCap * ZoneT1(ZoneNum) + TempIndCoef) / (AirCap + TempDepCoef); - } break; - default: - break; + } break; + case DataHeatBalance::SolutionAlgo::EulerMethod: { + this->ZT = (this->AirPowerCap * this->ZoneT1 + this->TempIndCoef) / (this->AirPowerCap + this->TempDepCoef); + } break; + default: + break; + } + // Update zone node temperature and thermostat temperature unless already updated in Room Air Model, + // calculate load correction factor + if (!state.dataRoomAirMod->anyNonMixingRoomAirModel) { + // Fully mixed + thisSystemNode.Temp = this->ZT; + // SpaceHB TODO: What to do here if this is for space + if (spaceNum == 0) { + state.dataHeatBalFanSys->TempTstatAir(zoneNum) = this->ZT; } - // Update zone node temperature and thermostat temperature unless already updated in Room Air Model, - // calculate load correction factor - if ((AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::Mixing) || (!AirModel(ZoneNum).SimAirModel)) { + state.dataHeatBalFanSys->LoadCorrectionFactor(zoneNum) = 1.0; + } else { + auto &thisAirModel = state.dataRoomAirMod->AirModel(zoneNum); + if ((thisAirModel.AirModelType == DataRoomAirModel::RoomAirModel::Mixing) || (!thisAirModel.SimAirModel)) { // Fully mixed - Node(ZoneNodeNum).Temp = ZT(ZoneNum); - state.dataHeatBalFanSys->TempTstatAir(ZoneNum) = ZT(ZoneNum); - state.dataHeatBalFanSys->LoadCorrectionFactor(ZoneNum) = 1.0; - } else if (state.dataRoomAirMod->IsZoneDV(ZoneNum) || state.dataRoomAirMod->IsZoneUI(ZoneNum)) { + thisSystemNode.Temp = this->ZT; + // SpaceHB TODO: What to do here if this is for space + if (spaceNum == 0) { + state.dataHeatBalFanSys->TempTstatAir(zoneNum) = this->ZT; + } + state.dataHeatBalFanSys->LoadCorrectionFactor(zoneNum) = 1.0; + } else if (state.dataRoomAirMod->IsZoneDV(zoneNum) || state.dataRoomAirMod->IsZoneUI(zoneNum)) { // UCSDDV: Not fully mixed - calculate factor to correct load for fully mixed assumption - if (SumSysMCp > SmallMassFlow) { - TempSupplyAir = SumSysMCpT / SumSysMCp; // Non-negligible flow, calculate supply air temperature - if (std::abs(TempSupplyAir - ZT(ZoneNum)) > state.dataHeatBal->TempConvergTol) { - state.dataHeatBalFanSys->LoadCorrectionFactor(ZoneNum) = - (TempSupplyAir - Node(ZoneNodeNum).Temp) / (TempSupplyAir - ZT(ZoneNum)); + // Space HB TODO: Space HB doesn't mix with DV etc. + if (this->SumSysMCp > DataHVACGlobals::SmallMassFlow) { + Real64 TempSupplyAir = this->SumSysMCpT / this->SumSysMCp; // Non-negligible flow, calculate supply air temperature + if (std::abs(TempSupplyAir - this->ZT) > state.dataHeatBal->TempConvergTol) { + state.dataHeatBalFanSys->LoadCorrectionFactor(zoneNum) = (TempSupplyAir - thisSystemNode.Temp) / (TempSupplyAir - this->ZT); // constrain value to something reasonable - state.dataHeatBalFanSys->LoadCorrectionFactor(ZoneNum) = max(-3.0, state.dataHeatBalFanSys->LoadCorrectionFactor(ZoneNum)); - state.dataHeatBalFanSys->LoadCorrectionFactor(ZoneNum) = min(3.0, state.dataHeatBalFanSys->LoadCorrectionFactor(ZoneNum)); + state.dataHeatBalFanSys->LoadCorrectionFactor(zoneNum) = max(-3.0, state.dataHeatBalFanSys->LoadCorrectionFactor(zoneNum)); + state.dataHeatBalFanSys->LoadCorrectionFactor(zoneNum) = min(3.0, state.dataHeatBalFanSys->LoadCorrectionFactor(zoneNum)); } else { - state.dataHeatBalFanSys->LoadCorrectionFactor(ZoneNum) = 1.0; // Indeterminate + state.dataHeatBalFanSys->LoadCorrectionFactor(zoneNum) = 1.0; // Indeterminate } } else { // Negligible flow, assume mixed - reasonable lagged starting value for first step time with significant flow - state.dataHeatBalFanSys->LoadCorrectionFactor(ZoneNum) = 1.0; - } - } else if (AirModel(ZoneNum).SimAirModel && ((AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::UserDefined) || - (AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::Mundt))) { - if (SumSysMCp > SmallMassFlow) { - TempSupplyAir = SumSysMCpT / SumSysMCp; // Non-negligible flow, calculate supply air temperature - if (std::abs(TempSupplyAir - ZT(ZoneNum)) > state.dataHeatBal->TempConvergTol) { - state.dataHeatBalFanSys->LoadCorrectionFactor(ZoneNum) = - (TempSupplyAir - Node(ZoneNodeNum).Temp) / (TempSupplyAir - ZT(ZoneNum)); + state.dataHeatBalFanSys->LoadCorrectionFactor(zoneNum) = 1.0; + } + } else if (thisAirModel.SimAirModel && ((thisAirModel.AirModelType == DataRoomAirModel::RoomAirModel::UserDefined) || + (thisAirModel.AirModelType == DataRoomAirModel::RoomAirModel::Mundt))) { + if (this->SumSysMCp > DataHVACGlobals::SmallMassFlow) { + Real64 TempSupplyAir = this->SumSysMCpT / this->SumSysMCp; // Non-negligible flow, calculate supply air temperature + if (std::abs(TempSupplyAir - this->ZT) > state.dataHeatBal->TempConvergTol) { + state.dataHeatBalFanSys->LoadCorrectionFactor(zoneNum) = (TempSupplyAir - thisSystemNode.Temp) / (TempSupplyAir - this->ZT); // constrain value - state.dataHeatBalFanSys->LoadCorrectionFactor(ZoneNum) = max(-3.0, state.dataHeatBalFanSys->LoadCorrectionFactor(ZoneNum)); - state.dataHeatBalFanSys->LoadCorrectionFactor(ZoneNum) = min(3.0, state.dataHeatBalFanSys->LoadCorrectionFactor(ZoneNum)); + state.dataHeatBalFanSys->LoadCorrectionFactor(zoneNum) = max(-3.0, state.dataHeatBalFanSys->LoadCorrectionFactor(zoneNum)); + state.dataHeatBalFanSys->LoadCorrectionFactor(zoneNum) = min(3.0, state.dataHeatBalFanSys->LoadCorrectionFactor(zoneNum)); } else { - state.dataHeatBalFanSys->LoadCorrectionFactor(ZoneNum) = 1.0; // Indeterminate + state.dataHeatBalFanSys->LoadCorrectionFactor(zoneNum) = 1.0; // Indeterminate } } else { // Negligible flow, assume mixed - reasonable lagged starting value for first step time with significant flow - state.dataHeatBalFanSys->LoadCorrectionFactor(ZoneNum) = 1.0; + state.dataHeatBalFanSys->LoadCorrectionFactor(zoneNum) = 1.0; } - } else if (AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { + } else if (thisAirModel.AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { // Zone node used in the RoomAirflowNetwork model - ZT(ZoneNum) = RoomAirflowNetworkZoneInfo(ZoneNum).Node(RoomAirflowNetworkZoneInfo(ZoneNum).ControlAirNodeID).AirTemp; - Node(ZoneNodeNum).Temp = ZT(ZoneNum); - state.dataHeatBalFanSys->TempTstatAir(ZoneNum) = ZT(ZoneNum); - state.dataHeatBalFanSys->LoadCorrectionFactor(ZoneNum) = 1.0; + this->ZT = state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(zoneNum) + .Node(state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(zoneNum).ControlAirNodeID) + .AirTemp; + thisSystemNode.Temp = this->ZT; + // SpaceHB TODO: What to do here if this is for space + if (spaceNum == 0) { + state.dataHeatBalFanSys->TempTstatAir(zoneNum) = this->ZT; + } + state.dataHeatBalFanSys->LoadCorrectionFactor(zoneNum) = 1.0; } else { - Node(ZoneNodeNum).Temp = ZT(ZoneNum); - state.dataHeatBalFanSys->TempTstatAir(ZoneNum) = ZT(ZoneNum); - state.dataHeatBalFanSys->LoadCorrectionFactor(ZoneNum) = 1.0; + thisSystemNode.Temp = this->ZT; + // SpaceHB TODO: What to do here if this is for space + if (spaceNum == 0) { + state.dataHeatBalFanSys->TempTstatAir(zoneNum) = this->ZT; + } + state.dataHeatBalFanSys->LoadCorrectionFactor(zoneNum) = 1.0; } + } - // Sensible load is the enthalpy into the zone minus the enthalpy that leaves the zone. - CpAir = PsyCpAirFnW(ZoneAirHumRat(ZoneNum)); - ZoneEnthalpyIn = SumSysMCpT; + // Sensible load is the enthalpy into the zone minus the enthalpy that leaves the zone. + Real64 CpAir = Psychrometrics::PsyCpAirFnW(this->ZoneAirHumRat); + Real64 ZoneEnthalpyIn = this->SumSysMCpT; - // SNLOAD is the single zone load, without Zone Multiplier or Zone List Multiplier - SNLoad = ZoneEnthalpyIn - (Node(ZoneNodeNum).MassFlowRate / ZoneMult) * CpAir * Node(ZoneNodeNum).Temp + - state.dataHeatBalFanSys->NonAirSystemResponse(ZoneNum) / ZoneMult + state.dataHeatBalFanSys->SysDepZoneLoadsLagged(ZoneNum); + // SNLOAD is the single zone load, without Zone Multiplier or Zone List Multiplier + SNLoad = ZoneEnthalpyIn - (thisSystemNode.MassFlowRate / ZoneMult) * CpAir * thisSystemNode.Temp + this->NonAirSystemResponse / ZoneMult + + this->SysDepZoneLoadsLagged; - } else { + } else { - // Heat balance coefficients for uncontrolled zone, i.e. without system air flow - TempDepCoef = SumHA + SumMCp; - TempIndCoef = SumIntGain + SumHATsurf - SumHATref + SumMCpT; + // Heat balance coefficients for uncontrolled zone, i.e. without system air flow + this->TempDepCoef = this->SumHA + this->SumMCp; + this->TempIndCoef = this->SumIntGain + this->SumHATsurf - this->SumHATref + this->SumMCpT; - // TempHistoryTerm = AirCap * (3.0 * ZTM1(ZoneNum) - (3.0/2.0) * ZTM2(ZoneNum) + (1.0/3.0) * ZTM3(ZoneNum)) !debug only + if (state.afn->distribution_simulated) { + this->TempIndCoef += state.afn->exchangeData(zoneNum).TotalSen; + } - if (state.afn->distribution_simulated) { - TempIndCoef += state.afn->exchangeData(ZoneNum).TotalSen; - } - // TempDepZnLd(ZoneNum) = (11.0/6.0) * AirCap + TempDepCoef - // TempIndZnLd(ZoneNum) = TempHistoryTerm + TempIndCoef - - // Solve for zone air temperature - switch (ZoneAirSolutionAlgo) { - case DataHeatBalance::SolutionAlgo::ThirdOrder: { - ZT(ZoneNum) = - (TempIndCoef + AirCap * (3.0 * state.dataHeatBalFanSys->ZTM1(ZoneNum) - (3.0 / 2.0) * state.dataHeatBalFanSys->ZTM2(ZoneNum) + - (1.0 / 3.0) * state.dataHeatBalFanSys->ZTM3(ZoneNum))) / - ((11.0 / 6.0) * AirCap + TempDepCoef); - // Exact solution - } break; - case DataHeatBalance::SolutionAlgo::AnalyticalSolution: { - if (TempDepCoef == 0.0) { // B=0 - ZT(ZoneNum) = ZoneT1(ZoneNum) + TempIndCoef / AirCap; - } else { - ZT(ZoneNum) = - (ZoneT1(ZoneNum) - TempIndCoef / TempDepCoef) * std::exp(min(700.0, -TempDepCoef / AirCap)) + TempIndCoef / TempDepCoef; - } - } break; - case DataHeatBalance::SolutionAlgo::EulerMethod: { - ZT(ZoneNum) = (AirCap * ZoneT1(ZoneNum) + TempIndCoef) / (AirCap + TempDepCoef); - } break; - default: - break; + // Solve for zone air temperature + switch (state.dataHeatBal->ZoneAirSolutionAlgo) { + case DataHeatBalance::SolutionAlgo::ThirdOrder: { + this->ZT = (this->TempIndCoef + this->AirPowerCap * (3.0 * this->ZTM[0] - (3.0 / 2.0) * this->ZTM[1] + (1.0 / 3.0) * this->ZTM[2])) / + ((11.0 / 6.0) * this->AirPowerCap + this->TempDepCoef); + // Exact solution + } break; + case DataHeatBalance::SolutionAlgo::AnalyticalSolution: { + if (this->TempDepCoef == 0.0) { // B=0 + this->ZT = this->ZoneT1 + this->TempIndCoef / this->AirPowerCap; + } else { + this->ZT = (this->ZoneT1 - this->TempIndCoef / this->TempDepCoef) * std::exp(min(700.0, -this->TempDepCoef / this->AirPowerCap)) + + this->TempIndCoef / this->TempDepCoef; } + } break; + case DataHeatBalance::SolutionAlgo::EulerMethod: { + this->ZT = (this->AirPowerCap * this->ZoneT1 + this->TempIndCoef) / (this->AirPowerCap + this->TempDepCoef); + } break; + default: + break; + } - if (AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { - ZT(ZoneNum) = RoomAirflowNetworkZoneInfo(ZoneNum).Node(RoomAirflowNetworkZoneInfo(ZoneNum).ControlAirNodeID).AirTemp; + // SpaceHB TODO: For now, room air model is only for zones + if (spaceNum == 0 && state.dataRoomAirMod->anyNonMixingRoomAirModel) { + if (state.dataRoomAirMod->AirModel(zoneNum).AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { + this->ZT = state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(zoneNum) + .Node(state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(zoneNum).ControlAirNodeID) + .AirTemp; } - - // No sensible load - SNLoad = 0.0; } - // Hybrid modeling start - if ((state.dataHybridModel->HybridModelZone(ZoneNum).InfiltrationCalc_T || - state.dataHybridModel->HybridModelZone(ZoneNum).InternalThermalMassCalc_T || - state.dataHybridModel->HybridModelZone(ZoneNum).PeopleCountCalc_T) && + // No sensible load + SNLoad = 0.0; + } + + // Hybrid modeling start + // SpaceHB TODO: For now, hybrid model is only for zones + if (spaceNum == 0 && state.dataHybridModel->FlagHybridModel) { + if ((state.dataHybridModel->HybridModelZone(zoneNum).InfiltrationCalc_T || + state.dataHybridModel->HybridModelZone(zoneNum).InternalThermalMassCalc_T || + state.dataHybridModel->HybridModelZone(zoneNum).PeopleCountCalc_T) && (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing)) { - InverseModelTemperature( - state, ZoneNum, SumIntGain, SumIntGainExceptPeople, SumHA, SumHATsurf, SumHATref, SumMCp, SumMCpT, SumSysMCp, SumSysMCpT, AirCap); + InverseModelTemperature(state, + zoneNum, + this->SumIntGain, + this->SumIntGainExceptPeople, + this->SumHA, + this->SumHATsurf, + this->SumHATref, + this->SumMCp, + this->SumMCpT, + this->SumSysMCp, + this->SumSysMCpT, + this->AirPowerCap); } + } - MAT(ZoneNum) = ZT(ZoneNum); + this->MAT = this->ZT; - // Determine sensible load heating/cooling rate and energy - state.dataHeatBal->ZoneSNLoadHeatRate(ZoneNum) = max(SNLoad, 0.0); - state.dataHeatBal->ZoneSNLoadCoolRate(ZoneNum) = std::abs(min(SNLoad, 0.0)); - state.dataHeatBal->ZoneSNLoadHeatEnergy(ZoneNum) = max(SNLoad, 0.0) * TimeStepSys * DataGlobalConstants::SecInHour; - state.dataHeatBal->ZoneSNLoadCoolEnergy(ZoneNum) = std::abs(min(SNLoad, 0.0) * TimeStepSys * DataGlobalConstants::SecInHour); + // Determine sensible load heating/cooling rate and energy + if (spaceNum > 0) { + state.dataZoneEnergyDemand->spaceSysEnergyDemand(spaceNum).reportZoneAirSystemSensibleLoads(state, SNLoad); + } else { + state.dataZoneEnergyDemand->ZoneSysEnergyDemand(zoneNum).reportZoneAirSystemSensibleLoads(state, SNLoad); + } - // Final humidity calcs - CorrectZoneHumRat(state, ZoneNum); + // Final humidity calcs + this->correctHumRat(state, zoneNum, spaceNum); - ZoneAirHumRat(ZoneNum) = state.dataHeatBalFanSys->ZoneAirHumRatTemp(ZoneNum); - state.dataZoneTempPredictorCorrector->ZoneAirRelHum(ZoneNum) = - 100.0 * PsyRhFnTdbWPb(state, ZT(ZoneNum), ZoneAirHumRat(ZoneNum), state.dataEnvrn->OutBaroPress, RoutineName); + this->ZoneAirHumRat = this->ZoneAirHumRatTemp; + this->ZoneAirRelHum = 100.0 * Psychrometrics::PsyRhFnTdbWPb(state, this->ZT, this->ZoneAirHumRat, state.dataEnvrn->OutBaroPress, RoutineName); - // ZoneTempChange is used by HVACManager to determine if the timestep needs to be shortened. - switch (ZoneAirSolutionAlgo) { - case DataHeatBalance::SolutionAlgo::ThirdOrder: { - if (state.dataRoomAirMod->IsZoneDV(ZoneNum)) { - if (state.dataRoomAirMod->ZoneDVMixedFlag(ZoneNum) == 0) { - ZoneTempChange = max(ZoneTempChange, - max(std::abs(state.dataRoomAirMod->ZTOC(ZoneNum) - state.dataRoomAirMod->ZTM1OC(ZoneNum)), - std::abs(state.dataRoomAirMod->ZTMX(ZoneNum) - state.dataRoomAirMod->ZTM1MX(ZoneNum)))); - } else { - ZoneTempChange = max(ZoneTempChange, std::abs(ZT(ZoneNum) - state.dataHeatBalFanSys->ZTM1(ZoneNum))); - } - } else if (state.dataRoomAirMod->IsZoneUI(ZoneNum)) { - if (state.dataRoomAirMod->ZoneUFMixedFlag(ZoneNum) == 0) { - ZoneTempChange = max(ZoneTempChange, - max(std::abs(state.dataRoomAirMod->ZTOC(ZoneNum) - state.dataRoomAirMod->ZTM1OC(ZoneNum)), - std::abs(state.dataRoomAirMod->ZTMX(ZoneNum) - state.dataRoomAirMod->ZTM1MX(ZoneNum)))); - } else { - ZoneTempChange = max(ZoneTempChange, std::abs(ZT(ZoneNum) - state.dataHeatBalFanSys->ZTM1(ZoneNum))); - } - } else { - ZoneTempChange = max(ZoneTempChange, std::abs(ZT(ZoneNum) - state.dataHeatBalFanSys->ZTM1(ZoneNum))); - } - } break; - case DataHeatBalance::SolutionAlgo::AnalyticalSolution: - case DataHeatBalance::SolutionAlgo::EulerMethod: { - if (state.dataRoomAirMod->IsZoneDV(ZoneNum)) { - if (state.dataRoomAirMod->ZoneDVMixedFlag(ZoneNum) == 0) { - ZoneTempChange = max(ZoneTempChange, - max(std::abs(state.dataRoomAirMod->ZTOC(ZoneNum) - state.dataRoomAirMod->Zone1OC(ZoneNum)), - std::abs(state.dataRoomAirMod->ZTMX(ZoneNum) - state.dataRoomAirMod->Zone1MX(ZoneNum)))); - } else { - ZoneTempChange = max(ZoneTempChange, std::abs(ZT(ZoneNum) - ZoneT1(ZoneNum))); - } - } else if (state.dataRoomAirMod->IsZoneUI(ZoneNum)) { - if (state.dataRoomAirMod->ZoneUFMixedFlag(ZoneNum) == 0) { - ZoneTempChange = max(ZoneTempChange, - max(std::abs(state.dataRoomAirMod->ZTOC(ZoneNum) - state.dataRoomAirMod->Zone1OC(ZoneNum)), - std::abs(state.dataRoomAirMod->ZTMX(ZoneNum) - state.dataRoomAirMod->Zone1MX(ZoneNum)))); - } else { - ZoneTempChange = max(ZoneTempChange, std::abs(ZT(ZoneNum) - ZoneT1(ZoneNum))); - } - } else { - ZoneTempChange = max(ZoneTempChange, std::abs(ZT(ZoneNum) - ZoneT1(ZoneNum))); - } - } break; - default: - break; + // tempChange is used by HVACManager to determine if the timestep needs to be shortened. + bool isMixed = true; + // SpaceHB TODO: For now, room air model is only for zones + if (spaceNum == 0 && state.dataRoomAirMod->anyNonMixingRoomAirModel) { + isMixed = !((state.dataRoomAirMod->IsZoneDV(zoneNum) && !state.dataRoomAirMod->ZoneDVMixedFlag(zoneNum)) || + (state.dataRoomAirMod->IsZoneUI(zoneNum) && !state.dataRoomAirMod->ZoneUFMixedFlag(zoneNum))); + } + switch (state.dataHeatBal->ZoneAirSolutionAlgo) { + case DataHeatBalance::SolutionAlgo::ThirdOrder: { + if (isMixed) { + tempChange = max(tempChange, std::abs(this->ZT - this->ZTM[0])); + } else { + tempChange = max(tempChange, + max(std::abs(state.dataRoomAirMod->ZTOC(zoneNum) - state.dataRoomAirMod->ZTM1OC(zoneNum)), + std::abs(state.dataRoomAirMod->ZTMX(zoneNum) - state.dataRoomAirMod->ZTM1MX(zoneNum)))); } + } break; + case DataHeatBalance::SolutionAlgo::AnalyticalSolution: + case DataHeatBalance::SolutionAlgo::EulerMethod: { + if (isMixed) { + tempChange = max(tempChange, std::abs(this->ZT - this->ZoneT1)); + } else { + tempChange = max(tempChange, + max(std::abs(state.dataRoomAirMod->ZTOC(zoneNum) - state.dataRoomAirMod->Zone1OC(zoneNum)), + std::abs(state.dataRoomAirMod->ZTMX(zoneNum) - state.dataRoomAirMod->Zone1MX(zoneNum)))); + } + } break; + default: + break; + } - CalcZoneComponentLoadSums(state, - ZoneNum, - TempDepCoef, - TempIndCoef, - state.dataHeatBal->ZnAirRpt(ZoneNum).SumIntGains, - state.dataHeatBal->ZnAirRpt(ZoneNum).SumHADTsurfs, - state.dataHeatBal->ZnAirRpt(ZoneNum).SumMCpDTzones, - state.dataHeatBal->ZnAirRpt(ZoneNum).SumMCpDtInfil, - state.dataHeatBal->ZnAirRpt(ZoneNum).SumMCpDTsystem, - state.dataHeatBal->ZnAirRpt(ZoneNum).SumNonAirSystem, - state.dataHeatBal->ZnAirRpt(ZoneNum).CzdTdt, - state.dataHeatBal->ZnAirRpt(ZoneNum).imBalance, - state.dataHeatBal->ZnAirRpt(ZoneNum).SumEnthalpyM, - state.dataHeatBal->ZnAirRpt(ZoneNum).SumEnthalpyH); - - } // ZoneNum + CalcZoneComponentLoadSums(state, + zoneNum, + this->TempDepCoef, + this->TempIndCoef, + state.dataHeatBal->ZnAirRpt(zoneNum).SumIntGains, + state.dataHeatBal->ZnAirRpt(zoneNum).SumHADTsurfs, + state.dataHeatBal->ZnAirRpt(zoneNum).SumMCpDTzones, + state.dataHeatBal->ZnAirRpt(zoneNum).SumMCpDtInfil, + state.dataHeatBal->ZnAirRpt(zoneNum).SumMCpDTsystem, + state.dataHeatBal->ZnAirRpt(zoneNum).SumNonAirSystem, + state.dataHeatBal->ZnAirRpt(zoneNum).CzdTdt, + state.dataHeatBal->ZnAirRpt(zoneNum).imBalance, + state.dataHeatBal->ZnAirRpt(zoneNum).SumEnthalpyM, + state.dataHeatBal->ZnAirRpt(zoneNum).SumEnthalpyH); + return tempChange; } void PushZoneTimestepHistories(EnergyPlusData &state) @@ -5316,58 +4487,65 @@ void PushZoneTimestepHistories(EnergyPlusData &state) // PURPOSE OF THIS SUBROUTINE: // push histories for timestep advancing - // SUBROUTINE ARGUMENT DEFINITIONS: - constexpr auto CorrectZoneAirTemp("CorrectZoneAirTemp"); + for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { + state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum).pushZoneTimestepHistory(state, zoneNum); + if (state.dataHeatBal->doSpaceHeatBalance) { + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).pushZoneTimestepHistory(state, zoneNum, spaceNum); + } + } + } +} + +void ZoneSpaceHeatBalanceData::pushZoneTimestepHistory(EnergyPlusData &state, int const zoneNum, int const spaceNum) +{ + + constexpr std::string_view routineName("pushTimestepHistories"); + assert(zoneNum > 0); - auto &ZT = state.dataHeatBalFanSys->ZT; - auto &AirModel = state.dataRoomAirMod->AirModel; + auto &thisAirModel = state.dataRoomAirMod->AirModel(zoneNum); // Push the temperature and humidity ratio histories - for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { - state.dataHeatBalFanSys->XM4T(ZoneNum) = state.dataHeatBalFanSys->XM3T(ZoneNum); - state.dataHeatBalFanSys->XM3T(ZoneNum) = state.dataHeatBalFanSys->XM2T(ZoneNum); - state.dataHeatBalFanSys->XM2T(ZoneNum) = state.dataHeatBalFanSys->XMAT(ZoneNum); - state.dataHeatBalFanSys->XMAT(ZoneNum) = state.dataHeatBalFanSys->ZTAV(ZoneNum); // using average for whole zone time step. - state.dataHeatBalFanSys->XMPT(ZoneNum) = ZT(ZoneNum); - - state.dataHeatBalFanSys->WZoneTimeMinus4(ZoneNum) = state.dataHeatBalFanSys->WZoneTimeMinus3(ZoneNum); - state.dataHeatBalFanSys->WZoneTimeMinus3(ZoneNum) = state.dataHeatBalFanSys->WZoneTimeMinus2(ZoneNum); - state.dataHeatBalFanSys->WZoneTimeMinus2(ZoneNum) = state.dataHeatBalFanSys->WZoneTimeMinus1(ZoneNum); - state.dataHeatBalFanSys->WZoneTimeMinus1(ZoneNum) = - state.dataHeatBalFanSys->ZoneAirHumRatAvg(ZoneNum); // using average for whole zone time step. - state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum) = state.dataHeatBalFanSys->ZoneAirHumRatTemp(ZoneNum); - state.dataHeatBalFanSys->WZoneTimeMinusP(ZoneNum) = state.dataHeatBalFanSys->ZoneAirHumRatTemp(ZoneNum); - state.dataZoneTempPredictorCorrector->ZoneAirRelHum(ZoneNum) = - 100.0 * - PsyRhFnTdbWPb(state, ZT(ZoneNum), state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum), state.dataEnvrn->OutBaroPress, CorrectZoneAirTemp); - - if (AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::UCSDDV || - AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::UCSDUFI || - AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::UCSDUFE) { - state.dataRoomAirMod->XM4TFloor(ZoneNum) = state.dataRoomAirMod->XM3TFloor(ZoneNum); - state.dataRoomAirMod->XM3TFloor(ZoneNum) = state.dataRoomAirMod->XM2TFloor(ZoneNum); - state.dataRoomAirMod->XM2TFloor(ZoneNum) = state.dataRoomAirMod->XMATFloor(ZoneNum); - state.dataRoomAirMod->XMATFloor(ZoneNum) = state.dataRoomAirMod->ZTFloor(ZoneNum); - state.dataRoomAirMod->MATFloor(ZoneNum) = state.dataRoomAirMod->ZTFloor(ZoneNum); - - state.dataRoomAirMod->XM4TOC(ZoneNum) = state.dataRoomAirMod->XM3TOC(ZoneNum); - state.dataRoomAirMod->XM3TOC(ZoneNum) = state.dataRoomAirMod->XM2TOC(ZoneNum); - state.dataRoomAirMod->XM2TOC(ZoneNum) = state.dataRoomAirMod->XMATOC(ZoneNum); - state.dataRoomAirMod->XMATOC(ZoneNum) = state.dataRoomAirMod->ZTOC(ZoneNum); - state.dataRoomAirMod->MATOC(ZoneNum) = state.dataRoomAirMod->ZTOC(ZoneNum); - - state.dataRoomAirMod->XM4TMX(ZoneNum) = state.dataRoomAirMod->XM3TMX(ZoneNum); - state.dataRoomAirMod->XM3TMX(ZoneNum) = state.dataRoomAirMod->XM2TMX(ZoneNum); - state.dataRoomAirMod->XM2TMX(ZoneNum) = state.dataRoomAirMod->XMATMX(ZoneNum); - state.dataRoomAirMod->XMATMX(ZoneNum) = state.dataRoomAirMod->ZTMX(ZoneNum); - state.dataRoomAirMod->MATMX(ZoneNum) = state.dataRoomAirMod->ZTMX(ZoneNum); + for (int iHistory = 3; iHistory >= 1; --iHistory) { + this->XMAT[iHistory] = this->XMAT[iHistory - 1]; + this->WPrevZoneTS[iHistory] = this->WPrevZoneTS[iHistory - 1]; + } + this->XMAT[0] = this->ZTAV; // using average for whole zone time step. + this->XMPT = this->ZT; + this->WPrevZoneTS[0] = this->ZoneAirHumRatAvg; // using average for whole zone time step. + this->ZoneAirHumRat = this->ZoneAirHumRatTemp; + this->WZoneTimeMinusP = this->ZoneAirHumRatTemp; + this->ZoneAirRelHum = 100.0 * Psychrometrics::PsyRhFnTdbWPb(state, this->ZT, this->ZoneAirHumRat, state.dataEnvrn->OutBaroPress, routineName); + + // SpaceHB TODO: For now, room air model is only for zones + if (spaceNum == 0) { + if (thisAirModel.AirModelType == DataRoomAirModel::RoomAirModel::UCSDDV || + thisAirModel.AirModelType == DataRoomAirModel::RoomAirModel::UCSDUFI || + thisAirModel.AirModelType == DataRoomAirModel::RoomAirModel::UCSDUFE) { + state.dataRoomAirMod->XM4TFloor(zoneNum) = state.dataRoomAirMod->XM3TFloor(zoneNum); + state.dataRoomAirMod->XM3TFloor(zoneNum) = state.dataRoomAirMod->XM2TFloor(zoneNum); + state.dataRoomAirMod->XM2TFloor(zoneNum) = state.dataRoomAirMod->XMATFloor(zoneNum); + state.dataRoomAirMod->XMATFloor(zoneNum) = state.dataRoomAirMod->ZTFloor(zoneNum); + state.dataRoomAirMod->MATFloor(zoneNum) = state.dataRoomAirMod->ZTFloor(zoneNum); + + state.dataRoomAirMod->XM4TOC(zoneNum) = state.dataRoomAirMod->XM3TOC(zoneNum); + state.dataRoomAirMod->XM3TOC(zoneNum) = state.dataRoomAirMod->XM2TOC(zoneNum); + state.dataRoomAirMod->XM2TOC(zoneNum) = state.dataRoomAirMod->XMATOC(zoneNum); + state.dataRoomAirMod->XMATOC(zoneNum) = state.dataRoomAirMod->ZTOC(zoneNum); + state.dataRoomAirMod->MATOC(zoneNum) = state.dataRoomAirMod->ZTOC(zoneNum); + + state.dataRoomAirMod->XM4TMX(zoneNum) = state.dataRoomAirMod->XM3TMX(zoneNum); + state.dataRoomAirMod->XM3TMX(zoneNum) = state.dataRoomAirMod->XM2TMX(zoneNum); + state.dataRoomAirMod->XM2TMX(zoneNum) = state.dataRoomAirMod->XMATMX(zoneNum); + state.dataRoomAirMod->XMATMX(zoneNum) = state.dataRoomAirMod->ZTMX(zoneNum); + state.dataRoomAirMod->MATMX(zoneNum) = state.dataRoomAirMod->ZTMX(zoneNum); } // for RoomAirflowNetwork model - if (AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { - for (int LoopNode = 1; LoopNode <= state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).NumOfAirNodes; ++LoopNode) { - auto &roomAirflowNetworkZoneInfo = state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(LoopNode); + if (thisAirModel.AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { + for (int LoopNode = 1; LoopNode <= state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(zoneNum).NumOfAirNodes; ++LoopNode) { + auto &roomAirflowNetworkZoneInfo = state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(zoneNum).Node(LoopNode); roomAirflowNetworkZoneInfo.AirTempX4 = roomAirflowNetworkZoneInfo.AirTempX3; roomAirflowNetworkZoneInfo.AirTempX3 = roomAirflowNetworkZoneInfo.AirTempX2; roomAirflowNetworkZoneInfo.AirTempX2 = roomAirflowNetworkZoneInfo.AirTempX1; @@ -5379,26 +4557,29 @@ void PushZoneTimestepHistories(EnergyPlusData &state) roomAirflowNetworkZoneInfo.HumRatX1 = roomAirflowNetworkZoneInfo.HumRat; } } + } - if (state.dataHeatBal->ZoneAirSolutionAlgo != DataHeatBalance::SolutionAlgo::ThirdOrder) { - state.dataHeatBalFanSys->ZoneTM2(ZoneNum) = state.dataHeatBalFanSys->ZoneTMX(ZoneNum); - state.dataHeatBalFanSys->ZoneTMX(ZoneNum) = state.dataHeatBalFanSys->ZTAV(ZoneNum); // using average for whole zone time step. - state.dataHeatBalFanSys->ZoneWM2(ZoneNum) = state.dataHeatBalFanSys->ZoneWMX(ZoneNum); - state.dataHeatBalFanSys->ZoneWMX(ZoneNum) = state.dataHeatBalFanSys->ZoneAirHumRatAvg(ZoneNum); // using average for whole zone time step. - if (AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::UCSDDV || - AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::UCSDUFI || - AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::UCSDUFE) { - state.dataRoomAirMod->ZoneM2Floor(ZoneNum) = state.dataRoomAirMod->ZoneMXFloor(ZoneNum); - state.dataRoomAirMod->ZoneMXFloor(ZoneNum) = state.dataRoomAirMod->ZTFloor(ZoneNum); // using average for whole zone time step. - state.dataRoomAirMod->ZoneM2OC(ZoneNum) = state.dataRoomAirMod->ZoneMXOC(ZoneNum); - state.dataRoomAirMod->ZoneMXOC(ZoneNum) = state.dataRoomAirMod->ZTOC(ZoneNum); // using average for whole zone time step. - state.dataRoomAirMod->ZoneM2MX(ZoneNum) = state.dataRoomAirMod->ZoneMXMX(ZoneNum); - state.dataRoomAirMod->ZoneMXMX(ZoneNum) = state.dataRoomAirMod->ZTMX(ZoneNum); // using average for whole zone time step. - } - - if (AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { - for (int LoopNode = 1; LoopNode <= state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).NumOfAirNodes; ++LoopNode) { - auto &roomAirflowNetworkZoneInfo = state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(LoopNode); + if (state.dataHeatBal->ZoneAirSolutionAlgo != DataHeatBalance::SolutionAlgo::ThirdOrder) { + this->ZoneTM2 = this->ZoneTMX; + this->ZoneTMX = this->ZTAV; // using average for whole zone time step. + this->ZoneWM2 = this->ZoneWMX; + this->ZoneWMX = this->ZoneAirHumRatAvg; // using average for whole zone time step. + // SpaceHB TODO: For now, room air model is only for zones + if (spaceNum == 0) { + if (thisAirModel.AirModelType == DataRoomAirModel::RoomAirModel::UCSDDV || + thisAirModel.AirModelType == DataRoomAirModel::RoomAirModel::UCSDUFI || + thisAirModel.AirModelType == DataRoomAirModel::RoomAirModel::UCSDUFE) { + state.dataRoomAirMod->ZoneM2Floor(zoneNum) = state.dataRoomAirMod->ZoneMXFloor(zoneNum); + state.dataRoomAirMod->ZoneMXFloor(zoneNum) = state.dataRoomAirMod->ZTFloor(zoneNum); // using average for whole zone time step. + state.dataRoomAirMod->ZoneM2OC(zoneNum) = state.dataRoomAirMod->ZoneMXOC(zoneNum); + state.dataRoomAirMod->ZoneMXOC(zoneNum) = state.dataRoomAirMod->ZTOC(zoneNum); // using average for whole zone time step. + state.dataRoomAirMod->ZoneM2MX(zoneNum) = state.dataRoomAirMod->ZoneMXMX(zoneNum); + state.dataRoomAirMod->ZoneMXMX(zoneNum) = state.dataRoomAirMod->ZTMX(zoneNum); // using average for whole zone time step. + } + + if (thisAirModel.AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { + for (int LoopNode = 1; LoopNode <= state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(zoneNum).NumOfAirNodes; ++LoopNode) { + auto &roomAirflowNetworkZoneInfo = state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(zoneNum).Node(LoopNode); roomAirflowNetworkZoneInfo.AirTempTM2 = roomAirflowNetworkZoneInfo.AirTempTMX; roomAirflowNetworkZoneInfo.AirTempTMX = roomAirflowNetworkZoneInfo.AirTemp; @@ -5407,7 +4588,7 @@ void PushZoneTimestepHistories(EnergyPlusData &state) } } } - } // zone loop + } } void PushSystemTimestepHistories(EnergyPlusData &state) @@ -5420,36 +4601,47 @@ void PushSystemTimestepHistories(EnergyPlusData &state) // PURPOSE OF THIS SUBROUTINE: // Push the temperature and humidity ratio histories back in time - for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { - state.dataHeatBalFanSys->DSXM4T(ZoneNum) = state.dataHeatBalFanSys->DSXM3T(ZoneNum); - state.dataHeatBalFanSys->DSXM3T(ZoneNum) = state.dataHeatBalFanSys->DSXM2T(ZoneNum); - state.dataHeatBalFanSys->DSXM2T(ZoneNum) = state.dataHeatBalFanSys->DSXMAT(ZoneNum); - state.dataHeatBalFanSys->DSXMAT(ZoneNum) = state.dataHeatBalFanSys->MAT(ZoneNum); - - state.dataHeatBalFanSys->DSWZoneTimeMinus4(ZoneNum) = state.dataHeatBalFanSys->DSWZoneTimeMinus3(ZoneNum); - state.dataHeatBalFanSys->DSWZoneTimeMinus3(ZoneNum) = state.dataHeatBalFanSys->DSWZoneTimeMinus2(ZoneNum); - state.dataHeatBalFanSys->DSWZoneTimeMinus2(ZoneNum) = state.dataHeatBalFanSys->DSWZoneTimeMinus1(ZoneNum); - state.dataHeatBalFanSys->DSWZoneTimeMinus1(ZoneNum) = state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum); - - if (state.dataRoomAirMod->IsZoneDV(ZoneNum) || state.dataRoomAirMod->IsZoneUI(ZoneNum)) { - state.dataRoomAirMod->DSXM4TFloor(ZoneNum) = state.dataRoomAirMod->DSXM3TFloor(ZoneNum); - state.dataRoomAirMod->DSXM3TFloor(ZoneNum) = state.dataRoomAirMod->DSXM2TFloor(ZoneNum); - state.dataRoomAirMod->DSXM2TFloor(ZoneNum) = state.dataRoomAirMod->DSXMATFloor(ZoneNum); - state.dataRoomAirMod->DSXMATFloor(ZoneNum) = state.dataRoomAirMod->MATFloor(ZoneNum); - - state.dataRoomAirMod->DSXM4TOC(ZoneNum) = state.dataRoomAirMod->DSXM3TOC(ZoneNum); - state.dataRoomAirMod->DSXM3TOC(ZoneNum) = state.dataRoomAirMod->DSXM2TOC(ZoneNum); - state.dataRoomAirMod->DSXM2TOC(ZoneNum) = state.dataRoomAirMod->DSXMATOC(ZoneNum); - state.dataRoomAirMod->DSXMATOC(ZoneNum) = state.dataRoomAirMod->MATOC(ZoneNum); - - state.dataRoomAirMod->DSXM4TMX(ZoneNum) = state.dataRoomAirMod->DSXM3TMX(ZoneNum); - state.dataRoomAirMod->DSXM3TMX(ZoneNum) = state.dataRoomAirMod->DSXM2TMX(ZoneNum); - state.dataRoomAirMod->DSXM2TMX(ZoneNum) = state.dataRoomAirMod->DSXMATMX(ZoneNum); - state.dataRoomAirMod->DSXMATMX(ZoneNum) = state.dataRoomAirMod->MATMX(ZoneNum); - } - if (state.dataRoomAirMod->AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { - for (int LoopNode = 1; LoopNode <= state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).NumOfAirNodes; ++LoopNode) { - auto &roomAirflowNetworkZoneInfo = state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(LoopNode); + for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { + state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum).pushSystemTimestepHistory(state, zoneNum); + if (state.dataHeatBal->doSpaceHeatBalance) { + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).pushSystemTimestepHistory(state, zoneNum, spaceNum); + } + } + } +} + +void ZoneSpaceHeatBalanceData::pushSystemTimestepHistory(EnergyPlusData &state, int const zoneNum, int const spaceNum) +{ + assert(zoneNum > 0); + for (int iHistory = 3; iHistory >= 1; --iHistory) { + this->DSXMAT[iHistory] = this->DSXMAT[iHistory - 1]; + this->DSWPrevZoneTS[iHistory] = this->DSWPrevZoneTS[iHistory - 1]; + } + this->DSXMAT[0] = this->MAT; + this->DSWPrevZoneTS[0] = this->ZoneAirHumRat; + + // SpaceHB TODO: For now, room air model is only for zones + if (spaceNum == 0 && state.dataRoomAirMod->anyNonMixingRoomAirModel) { + if (state.dataRoomAirMod->IsZoneDV(zoneNum) || state.dataRoomAirMod->IsZoneUI(zoneNum)) { + state.dataRoomAirMod->DSXM4TFloor(zoneNum) = state.dataRoomAirMod->DSXM3TFloor(zoneNum); + state.dataRoomAirMod->DSXM3TFloor(zoneNum) = state.dataRoomAirMod->DSXM2TFloor(zoneNum); + state.dataRoomAirMod->DSXM2TFloor(zoneNum) = state.dataRoomAirMod->DSXMATFloor(zoneNum); + state.dataRoomAirMod->DSXMATFloor(zoneNum) = state.dataRoomAirMod->MATFloor(zoneNum); + + state.dataRoomAirMod->DSXM4TOC(zoneNum) = state.dataRoomAirMod->DSXM3TOC(zoneNum); + state.dataRoomAirMod->DSXM3TOC(zoneNum) = state.dataRoomAirMod->DSXM2TOC(zoneNum); + state.dataRoomAirMod->DSXM2TOC(zoneNum) = state.dataRoomAirMod->DSXMATOC(zoneNum); + state.dataRoomAirMod->DSXMATOC(zoneNum) = state.dataRoomAirMod->MATOC(zoneNum); + + state.dataRoomAirMod->DSXM4TMX(zoneNum) = state.dataRoomAirMod->DSXM3TMX(zoneNum); + state.dataRoomAirMod->DSXM3TMX(zoneNum) = state.dataRoomAirMod->DSXM2TMX(zoneNum); + state.dataRoomAirMod->DSXM2TMX(zoneNum) = state.dataRoomAirMod->DSXMATMX(zoneNum); + state.dataRoomAirMod->DSXMATMX(zoneNum) = state.dataRoomAirMod->MATMX(zoneNum); + } + if (state.dataRoomAirMod->AirModel(zoneNum).AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { + for (int LoopNode = 1; LoopNode <= state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(zoneNum).NumOfAirNodes; ++LoopNode) { + auto &roomAirflowNetworkZoneInfo = state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(zoneNum).Node(LoopNode); roomAirflowNetworkZoneInfo.AirTempDSX4 = roomAirflowNetworkZoneInfo.AirTempDSX3; roomAirflowNetworkZoneInfo.AirTempDSX3 = roomAirflowNetworkZoneInfo.AirTempDSX2; roomAirflowNetworkZoneInfo.AirTempDSX2 = roomAirflowNetworkZoneInfo.AirTempDSX1; @@ -5464,26 +4656,26 @@ void PushSystemTimestepHistories(EnergyPlusData &state) } if (state.dataHeatBal->ZoneAirSolutionAlgo != DataHeatBalance::SolutionAlgo::ThirdOrder) { - for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { - state.dataHeatBalFanSys->ZoneTM2(ZoneNum) = state.dataHeatBalFanSys->ZoneTMX(ZoneNum); - state.dataHeatBalFanSys->ZoneTMX(ZoneNum) = state.dataHeatBalFanSys->MAT(ZoneNum); // using average for whole zone time step. - state.dataHeatBalFanSys->ZoneWM2(ZoneNum) = state.dataHeatBalFanSys->ZoneWMX(ZoneNum); - state.dataHeatBalFanSys->ZoneWMX(ZoneNum) = - state.dataHeatBalFanSys->ZoneAirHumRatTemp(ZoneNum); // using average for whole zone time step. - - if (state.dataRoomAirMod->AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::UCSDDV || - state.dataRoomAirMod->AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::UCSDUFI || - state.dataRoomAirMod->AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::UCSDUFE) { - state.dataRoomAirMod->ZoneM2Floor(ZoneNum) = state.dataRoomAirMod->ZoneMXFloor(ZoneNum); - state.dataRoomAirMod->ZoneMXFloor(ZoneNum) = state.dataRoomAirMod->ZTFloor(ZoneNum); // using average for whole zone time step. - state.dataRoomAirMod->ZoneM2OC(ZoneNum) = state.dataRoomAirMod->ZoneMXOC(ZoneNum); - state.dataRoomAirMod->ZoneMXOC(ZoneNum) = state.dataRoomAirMod->ZTOC(ZoneNum); // using average for whole zone time step. - state.dataRoomAirMod->ZoneM2MX(ZoneNum) = state.dataRoomAirMod->ZoneMXMX(ZoneNum); - state.dataRoomAirMod->ZoneMXMX(ZoneNum) = state.dataRoomAirMod->ZTMX(ZoneNum); // using average for whole zone time step. - } - if (state.dataRoomAirMod->AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { - for (int LoopNode = 1; LoopNode <= state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).NumOfAirNodes; ++LoopNode) { - auto &roomAirflowNetworkZoneInfo = state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(LoopNode); + this->ZoneTM2 = this->ZoneTMX; + this->ZoneTMX = this->MAT; // using average for whole zone time step. + this->ZoneWM2 = this->ZoneWMX; + this->ZoneWMX = this->ZoneAirHumRatTemp; // using average for whole zone time step. + + // SpaceHB TODO: For now, room air model is only for zones + if (spaceNum == 0) { + if (state.dataRoomAirMod->AirModel(zoneNum).AirModelType == DataRoomAirModel::RoomAirModel::UCSDDV || + state.dataRoomAirMod->AirModel(zoneNum).AirModelType == DataRoomAirModel::RoomAirModel::UCSDUFI || + state.dataRoomAirMod->AirModel(zoneNum).AirModelType == DataRoomAirModel::RoomAirModel::UCSDUFE) { + state.dataRoomAirMod->ZoneM2Floor(zoneNum) = state.dataRoomAirMod->ZoneMXFloor(zoneNum); + state.dataRoomAirMod->ZoneMXFloor(zoneNum) = state.dataRoomAirMod->ZTFloor(zoneNum); // using average for whole zone time step. + state.dataRoomAirMod->ZoneM2OC(zoneNum) = state.dataRoomAirMod->ZoneMXOC(zoneNum); + state.dataRoomAirMod->ZoneMXOC(zoneNum) = state.dataRoomAirMod->ZTOC(zoneNum); // using average for whole zone time step. + state.dataRoomAirMod->ZoneM2MX(zoneNum) = state.dataRoomAirMod->ZoneMXMX(zoneNum); + state.dataRoomAirMod->ZoneMXMX(zoneNum) = state.dataRoomAirMod->ZTMX(zoneNum); // using average for whole zone time step. + } + if (state.dataRoomAirMod->AirModel(zoneNum).AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { + for (int LoopNode = 1; LoopNode <= state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(zoneNum).NumOfAirNodes; ++LoopNode) { + auto &roomAirflowNetworkZoneInfo = state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(zoneNum).Node(LoopNode); roomAirflowNetworkZoneInfo.AirTempTM2 = roomAirflowNetworkZoneInfo.AirTempTMX; roomAirflowNetworkZoneInfo.AirTempTMX = roomAirflowNetworkZoneInfo.AirTemp; @@ -5504,36 +4696,47 @@ void RevertZoneTimestepHistories(EnergyPlusData &state) // PURPOSE OF THIS SUBROUTINE: // Revert the temperature and humidity ratio histories - for (int ZoneNum = 1; ZoneNum <= state.dataGlobal->NumOfZones; ++ZoneNum) { - state.dataHeatBalFanSys->XMAT(ZoneNum) = state.dataHeatBalFanSys->XM2T(ZoneNum); - state.dataHeatBalFanSys->XM2T(ZoneNum) = state.dataHeatBalFanSys->XM3T(ZoneNum); - state.dataHeatBalFanSys->XM3T(ZoneNum) = state.dataHeatBalFanSys->XM4T(ZoneNum); + for (int zoneNum = 1; zoneNum <= state.dataGlobal->NumOfZones; ++zoneNum) { + state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum).revertZoneTimestepHistory(state, zoneNum); + if (state.dataHeatBal->doSpaceHeatBalance) { + for (int spaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + state.dataZoneTempPredictorCorrector->spaceHeatBalance(spaceNum).revertZoneTimestepHistory(state, zoneNum, spaceNum); + } + } + } +} + +void ZoneSpaceHeatBalanceData::revertZoneTimestepHistory(EnergyPlusData &state, int const zoneNum, int const spaceNum) +{ + assert(zoneNum > 0); - // ZoneAirHumRat(ZoneNum) = WZoneTimeMinus1(ZoneNum) - state.dataHeatBalFanSys->WZoneTimeMinus1(ZoneNum) = state.dataHeatBalFanSys->WZoneTimeMinus2(ZoneNum); - state.dataHeatBalFanSys->WZoneTimeMinus2(ZoneNum) = state.dataHeatBalFanSys->WZoneTimeMinus3(ZoneNum); - state.dataHeatBalFanSys->WZoneTimeMinus3(ZoneNum) = state.dataHeatBalFanSys->WZoneTimeMinus4(ZoneNum); + for (int iHistory = 0; iHistory <= 2; ++iHistory) { + this->XMAT[iHistory] = this->XMAT[iHistory + 1]; + this->WPrevZoneTS[iHistory] = this->WPrevZoneTS[iHistory + 1]; + } - if (state.dataRoomAirMod->AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::UCSDDV || - state.dataRoomAirMod->AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::UCSDUFI || - state.dataRoomAirMod->AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::UCSDUFE) { + // SpaceHB TODO: For now, room air model is only for zones + if (spaceNum == 0) { + if (state.dataRoomAirMod->AirModel(zoneNum).AirModelType == DataRoomAirModel::RoomAirModel::UCSDDV || + state.dataRoomAirMod->AirModel(zoneNum).AirModelType == DataRoomAirModel::RoomAirModel::UCSDUFI || + state.dataRoomAirMod->AirModel(zoneNum).AirModelType == DataRoomAirModel::RoomAirModel::UCSDUFE) { - state.dataRoomAirMod->XMATFloor(ZoneNum) = state.dataRoomAirMod->XM2TFloor(ZoneNum); - state.dataRoomAirMod->XM2TFloor(ZoneNum) = state.dataRoomAirMod->XM3TFloor(ZoneNum); - state.dataRoomAirMod->XM3TFloor(ZoneNum) = state.dataRoomAirMod->XM4TFloor(ZoneNum); + state.dataRoomAirMod->XMATFloor(zoneNum) = state.dataRoomAirMod->XM2TFloor(zoneNum); + state.dataRoomAirMod->XM2TFloor(zoneNum) = state.dataRoomAirMod->XM3TFloor(zoneNum); + state.dataRoomAirMod->XM3TFloor(zoneNum) = state.dataRoomAirMod->XM4TFloor(zoneNum); - state.dataRoomAirMod->XMATOC(ZoneNum) = state.dataRoomAirMod->XM2TOC(ZoneNum); - state.dataRoomAirMod->XM2TOC(ZoneNum) = state.dataRoomAirMod->XM3TOC(ZoneNum); - state.dataRoomAirMod->XM3TOC(ZoneNum) = state.dataRoomAirMod->XM4TOC(ZoneNum); + state.dataRoomAirMod->XMATOC(zoneNum) = state.dataRoomAirMod->XM2TOC(zoneNum); + state.dataRoomAirMod->XM2TOC(zoneNum) = state.dataRoomAirMod->XM3TOC(zoneNum); + state.dataRoomAirMod->XM3TOC(zoneNum) = state.dataRoomAirMod->XM4TOC(zoneNum); - state.dataRoomAirMod->XMATMX(ZoneNum) = state.dataRoomAirMod->XM2TMX(ZoneNum); - state.dataRoomAirMod->XM2TMX(ZoneNum) = state.dataRoomAirMod->XM3TMX(ZoneNum); - state.dataRoomAirMod->XM3TMX(ZoneNum) = state.dataRoomAirMod->XM4TMX(ZoneNum); + state.dataRoomAirMod->XMATMX(zoneNum) = state.dataRoomAirMod->XM2TMX(zoneNum); + state.dataRoomAirMod->XM2TMX(zoneNum) = state.dataRoomAirMod->XM3TMX(zoneNum); + state.dataRoomAirMod->XM3TMX(zoneNum) = state.dataRoomAirMod->XM4TMX(zoneNum); } - if (state.dataRoomAirMod->AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { - for (int LoopNode = 1; LoopNode <= state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).NumOfAirNodes; ++LoopNode) { - auto &roomAirflowNetworkZoneInfo = state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).Node(LoopNode); + if (state.dataRoomAirMod->AirModel(zoneNum).AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { + for (int LoopNode = 1; LoopNode <= state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(zoneNum).NumOfAirNodes; ++LoopNode) { + auto &roomAirflowNetworkZoneInfo = state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(zoneNum).Node(LoopNode); roomAirflowNetworkZoneInfo.AirTempX1 = roomAirflowNetworkZoneInfo.AirTempX2; roomAirflowNetworkZoneInfo.AirTempX2 = roomAirflowNetworkZoneInfo.AirTempX3; roomAirflowNetworkZoneInfo.AirTempX3 = roomAirflowNetworkZoneInfo.AirTempX4; @@ -5546,7 +4749,7 @@ void RevertZoneTimestepHistories(EnergyPlusData &state) } } -void CorrectZoneHumRat(EnergyPlusData &state, int const ZoneNum) +void ZoneSpaceHeatBalanceData::correctHumRat(EnergyPlusData &state, int const zoneNum, int const spaceNum) { // SUBROUTINE INFORMATION: @@ -5554,18 +4757,19 @@ void CorrectZoneHumRat(EnergyPlusData &state, int const ZoneNum) // DATE WRITTEN 2000 // REFERENCES: Routine FinalZnCalcs - FINAL ZONE CALCULATIONS, authored by Dale Herron for BLAST. - static constexpr std::string_view RoutineName("CorrectZoneHumRat"); + assert(zoneNum > 0); + static constexpr std::string_view RoutineName("correctHumRat"); Real64 MoistureMassFlowRate = 0.0; Real64 ZoneMassFlowRate = 0.0; - auto &zone = state.dataHeatBal->Zone(ZoneNum); + auto &zone = state.dataHeatBal->Zone(zoneNum); int ZoneMult = zone.Multiplier * zone.ListMultiplier; bool ControlledZoneAirFlag = zone.IsControlled; bool ZoneRetPlenumAirFlag = zone.IsReturnPlenum; bool ZoneSupPlenumAirFlag = zone.IsSupplyPlenum; if (ControlledZoneAirFlag) { // If there is system flow then calculate the flow rates - auto &zoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(ZoneNum); + 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)); @@ -5606,8 +4810,7 @@ void CorrectZoneHumRat(EnergyPlusData &state, int const ZoneNum) } // Calculate hourly humidity ratio from infiltration + humidity added from latent load + system added moisture - Real64 LatentGain = state.dataHeatBalFanSys->ZoneLatentGain(ZoneNum) + state.dataHeatBalFanSys->SumLatentHTRadSys(ZoneNum) + - state.dataHeatBalFanSys->SumLatentPool(ZoneNum); + Real64 LatentGain = this->ZoneLatentGain + state.dataHeatBalFanSys->SumLatentHTRadSys(zoneNum) + state.dataHeatBalFanSys->SumLatentPool(zoneNum); Real64 SysTimeStepInSeconds = DataGlobalConstants::SecInHour * state.dataHVACGlobal->TimeStepSys; @@ -5616,124 +4819,121 @@ void CorrectZoneHumRat(EnergyPlusData &state, int const ZoneNum) // heat balance. There are 2 cases that should be considered, system // operating and system shutdown. - auto &ZT = state.dataHeatBalFanSys->ZT(ZoneNum); - Real64 RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, ZT, state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum), RoutineName); - Real64 H2OHtOfVap = PsyHgAirFnWTdb(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum), ZT); + Real64 const RhoAir = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, this->ZT, this->ZoneAirHumRat, RoutineName); + Real64 const H2OHtOfVap = Psychrometrics::PsyHgAirFnWTdb(this->ZoneAirHumRat, this->ZT); - Real64 B = (LatentGain / H2OHtOfVap) + - ((state.dataHeatBalFanSys->OAMFL(ZoneNum) + state.dataHeatBalFanSys->VAMFL(ZoneNum) + state.dataHeatBalFanSys->CTMFL(ZoneNum)) * - state.dataEnvrn->OutHumRat) + - state.dataHeatBalFanSys->EAMFLxHumRat(ZoneNum) + (MoistureMassFlowRate) + state.dataHeatBalFanSys->SumHmARaW(ZoneNum) + - state.dataHeatBalFanSys->MixingMassFlowXHumRat(ZoneNum) + state.dataHeatBalFanSys->MDotOA(ZoneNum) * state.dataEnvrn->OutHumRat; - Real64 A = ZoneMassFlowRate + state.dataHeatBalFanSys->OAMFL(ZoneNum) + state.dataHeatBalFanSys->VAMFL(ZoneNum) + - state.dataHeatBalFanSys->EAMFL(ZoneNum) + state.dataHeatBalFanSys->CTMFL(ZoneNum) + state.dataHeatBalFanSys->SumHmARa(ZoneNum) + - state.dataHeatBalFanSys->MixingMassFlowZone(ZoneNum) + state.dataHeatBalFanSys->MDotOA(ZoneNum); + Real64 B = (LatentGain / H2OHtOfVap) + ((this->OAMFL + this->VAMFL + this->CTMFL) * state.dataEnvrn->OutHumRat) + this->EAMFLxHumRat + + (MoistureMassFlowRate) + this->SumHmARaW + this->MixingMassFlowXHumRat + this->MDotOA * state.dataEnvrn->OutHumRat; + Real64 A = ZoneMassFlowRate + this->OAMFL + this->VAMFL + this->EAMFL + this->CTMFL + this->SumHmARa + this->MixingMassFlowZone + this->MDotOA; if (state.afn->multizone_always_simulated || (state.afn->simulation_control.type == AirflowNetwork::ControlType::MultizoneWithDistributionOnlyDuringFanOperation && state.afn->AirflowNetworkFanActivated)) { - auto &exchangeData = state.afn->exchangeData(ZoneNum); + auto &exchangeData = state.afn->exchangeData(zoneNum); // Multizone airflow calculated in AirflowNetwork - B = (LatentGain / H2OHtOfVap) + (exchangeData.SumMHrW + exchangeData.SumMMHrW) + (MoistureMassFlowRate) + - state.dataHeatBalFanSys->SumHmARaW(ZoneNum); - A = ZoneMassFlowRate + exchangeData.SumMHr + exchangeData.SumMMHr + state.dataHeatBalFanSys->SumHmARa(ZoneNum); + B = (LatentGain / H2OHtOfVap) + (exchangeData.SumMHrW + exchangeData.SumMMHrW) + (MoistureMassFlowRate) + this->SumHmARaW; + A = ZoneMassFlowRate + exchangeData.SumMHr + exchangeData.SumMMHr + this->SumHmARa; } Real64 C = RhoAir * zone.Volume * zone.ZoneVolCapMultpMoist / SysTimeStepInSeconds; if (state.afn->distribution_simulated) { - B += state.afn->exchangeData(ZoneNum).TotalLat; + B += state.afn->exchangeData(zoneNum).TotalLat; } // Use a 3rd order derivative to predict final zone humidity ratio and // smooth the changes using the zone air capacitance. - auto &zoneAirHumRatTemp = state.dataHeatBalFanSys->ZoneAirHumRatTemp(ZoneNum); + // auto &zoneAirHumRatTemp = this->ZoneAirHumRatTemp; + // auto &zoneW1 = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).ZoneW1; switch (state.dataHeatBal->ZoneAirSolutionAlgo) { case DataHeatBalance::SolutionAlgo::ThirdOrder: { - zoneAirHumRatTemp = (B + C * (3.0 * state.dataHeatBalFanSys->WZoneTimeMinus1Temp(ZoneNum) - - (3.0 / 2.0) * state.dataHeatBalFanSys->WZoneTimeMinus2Temp(ZoneNum) + - (1.0 / 3.0) * state.dataHeatBalFanSys->WZoneTimeMinus3Temp(ZoneNum))) / - ((11.0 / 6.0) * C + A); + this->ZoneAirHumRatTemp = + (B + C * (3.0 * this->WPrevZoneTSTemp[0] - (3.0 / 2.0) * this->WPrevZoneTSTemp[1] + (1.0 / 3.0) * this->WPrevZoneTSTemp[2])) / + ((11.0 / 6.0) * C + A); // Exact solution } break; case DataHeatBalance::SolutionAlgo::AnalyticalSolution: { if (A == 0.0) { // B=0 - zoneAirHumRatTemp = state.dataHeatBalFanSys->ZoneW1(ZoneNum) + B / C; + this->ZoneAirHumRatTemp = this->ZoneW1 + B / C; } else { - zoneAirHumRatTemp = (state.dataHeatBalFanSys->ZoneW1(ZoneNum) - B / A) * std::exp(min(700.0, -A / C)) + B / A; + this->ZoneAirHumRatTemp = (this->ZoneW1 - B / A) * std::exp(min(700.0, -A / C)) + B / A; } } break; case DataHeatBalance::SolutionAlgo::EulerMethod: { - zoneAirHumRatTemp = (C * state.dataHeatBalFanSys->ZoneW1(ZoneNum) + B) / (C + A); + this->ZoneAirHumRatTemp = (C * this->ZoneW1 + B) / (C + A); } break; default: break; } // Set the humidity ratio to zero if the zone has been dried out - if (zoneAirHumRatTemp < 0.0) zoneAirHumRatTemp = 0.0; + if (this->ZoneAirHumRatTemp < 0.0) this->ZoneAirHumRatTemp = 0.0; // Check to make sure that is saturated there is condensation in the zone // by resetting to saturation conditions. - Real64 WZSat = PsyWFnTdbRhPb(state, ZT, 1.0, state.dataEnvrn->OutBaroPress, RoutineName); + Real64 const WZSat = Psychrometrics::PsyWFnTdbRhPb(state, this->ZT, 1.0, state.dataEnvrn->OutBaroPress, RoutineName); - if (zoneAirHumRatTemp > WZSat) zoneAirHumRatTemp = WZSat; + if (this->ZoneAirHumRatTemp > WZSat) this->ZoneAirHumRatTemp = WZSat; - if (state.dataRoomAirMod->AirModel(ZoneNum).AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { - zoneAirHumRatTemp = state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum) - .Node(state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(ZoneNum).ControlAirNodeID) - .HumRat; + if (state.dataRoomAirMod->AirModel(zoneNum).AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { + this->ZoneAirHumRatTemp = state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(zoneNum) + .Node(state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(zoneNum).ControlAirNodeID) + .HumRat; } // HybridModel with measured humidity ratio begins - if ((state.dataHybridModel->HybridModelZone(ZoneNum).InfiltrationCalc_H || state.dataHybridModel->HybridModelZone(ZoneNum).PeopleCountCalc_H) && - (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing)) { - Real64 LatentGainExceptPeople = 0.0; - if (state.dataHybridModel->HybridModelZone(ZoneNum).PeopleCountCalc_H) { - LatentGainExceptPeople = state.dataHeatBalFanSys->ZoneLatentGainExceptPeople(ZoneNum) + - state.dataHeatBalFanSys->SumLatentHTRadSys(ZoneNum) + state.dataHeatBalFanSys->SumLatentPool(ZoneNum); - } + // SpaceHB TODO: For now, hybrid model is only for zones + if (spaceNum == 0 && state.dataHybridModel->FlagHybridModel) { + if ((state.dataHybridModel->HybridModelZone(zoneNum).InfiltrationCalc_H || + state.dataHybridModel->HybridModelZone(zoneNum).PeopleCountCalc_H) && + (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing)) { + Real64 LatentGainExceptPeople = 0.0; + if (state.dataHybridModel->HybridModelZone(zoneNum).PeopleCountCalc_H) { + LatentGainExceptPeople = this->ZoneLatentGainExceptPeople + state.dataHeatBalFanSys->SumLatentHTRadSys(zoneNum) + + state.dataHeatBalFanSys->SumLatentPool(zoneNum); + } - InverseModelHumidity(state, ZoneNum, LatentGain, LatentGainExceptPeople, ZoneMassFlowRate, MoistureMassFlowRate, H2OHtOfVap, RhoAir); + InverseModelHumidity(state, zoneNum, LatentGain, LatentGainExceptPeople, ZoneMassFlowRate, MoistureMassFlowRate, H2OHtOfVap, RhoAir); + } } // Now put the calculated info into the actual zone nodes; ONLY if there is zone air flow, i.e. controlled zone or plenum zone int ZoneNodeNum = zone.SystemZoneNodeNumber; + if (spaceNum > 0) { + ZoneNodeNum = state.dataHeatBal->space(spaceNum).SystemZoneNodeNumber; + } if (ZoneNodeNum > 0) { - state.dataLoopNodes->Node(ZoneNodeNum).HumRat = zoneAirHumRatTemp; - state.dataLoopNodes->Node(ZoneNodeNum).Enthalpy = PsyHFnTdbW(ZT, zoneAirHumRatTemp); + state.dataLoopNodes->Node(ZoneNodeNum).HumRat = this->ZoneAirHumRatTemp; + state.dataLoopNodes->Node(ZoneNodeNum).Enthalpy = Psychrometrics::PsyHFnTdbW(this->ZT, this->ZoneAirHumRatTemp); } if (state.dataHeatBal->DoLatentSizing) { - state.dataHeatBal->latentReports(ZoneNum).ZoneLTLoadHeatRate = std::abs(min(LatentGain, 0.0)); - state.dataHeatBal->latentReports(ZoneNum).ZoneLTLoadCoolRate = max(LatentGain, 0.0); - state.dataHeatBal->latentReports(ZoneNum).ZoneLTLoadHeatEnergy = - state.dataHeatBal->latentReports(ZoneNum).ZoneLTLoadHeatRate * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour; - state.dataHeatBal->latentReports(ZoneNum).ZoneLTLoadCoolEnergy = - state.dataHeatBal->latentReports(ZoneNum).ZoneLTLoadCoolRate * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour; - Real64 sensibleLoad = state.dataHeatBal->ZoneSNLoadHeatRate(ZoneNum) + state.dataHeatBal->ZoneSNLoadCoolRate(ZoneNum); - if ((sensibleLoad + LatentGain) != 0.0) { - state.dataHeatBal->latentReports(ZoneNum).ZoneSensibleHeatRatio = sensibleLoad / (sensibleLoad + LatentGain); - } else if (sensibleLoad != 0.0) { - state.dataHeatBal->latentReports(ZoneNum).ZoneSensibleHeatRatio = 1.0; + Real64 sensibleLoad = 0.0; + Real64 pSat = Psychrometrics::PsyPsatFnTemp(state, this->ZT, RoutineName); + Real64 Tdp = Psychrometrics::PsyTdpFnWPb(state, this->ZoneAirHumRatTemp, state.dataEnvrn->StdBaroPress); + Real64 vaporPressureDiff = pSat - Psychrometrics::PsyPsatFnTemp(state, Tdp, RoutineName); + if (spaceNum > 0) { + sensibleLoad = state.dataZoneEnergyDemand->spaceSysEnergyDemand(spaceNum).ZoneSNLoadHeatRate + + state.dataZoneEnergyDemand->spaceSysEnergyDemand(spaceNum).ZoneSNLoadCoolRate; + state.dataZoneEnergyDemand->spaceSysMoistureDemand(spaceNum).reportZoneAirSystemMoistureLoads( + state, LatentGain, sensibleLoad, vaporPressureDiff); } else { - state.dataHeatBal->latentReports(ZoneNum).ZoneSensibleHeatRatio = 0.0; + sensibleLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(zoneNum).ZoneSNLoadHeatRate + + state.dataZoneEnergyDemand->ZoneSysEnergyDemand(zoneNum).ZoneSNLoadCoolRate; + state.dataZoneEnergyDemand->ZoneSysMoistureDemand(zoneNum).reportZoneAirSystemMoistureLoads( + state, LatentGain, sensibleLoad, vaporPressureDiff); } - Real64 pSat = PsyPsatFnTemp(state, ZT, RoutineName); - Real64 Tdp = Psychrometrics::PsyTdpFnWPb(state, state.dataHeatBalFanSys->ZoneAirHumRatTemp(ZoneNum), state.dataEnvrn->StdBaroPress); - state.dataHeatBal->latentReports(ZoneNum).ZoneVaporPressureDifference = pSat - PsyPsatFnTemp(state, Tdp, RoutineName); } } void DownInterpolate4HistoryValues(Real64 const OldTimeStep, Real64 const NewTimeStep, - Real64 &oldVal0, - Real64 &oldVal1, - Real64 &oldVal2, + Real64 const oldVal0, + Real64 const oldVal1, + Real64 const oldVal2, Real64 &newVal0, Real64 &newVal1, Real64 &newVal2, - Real64 &newVal3, // unused 1208 - Real64 &newVal4 // unused 1208 -) + Real64 &newVal3, + Real64 &newVal4) { // SUBROUTINE INFORMATION: // AUTHOR Brent Griffith @@ -5747,7 +4947,7 @@ void DownInterpolate4HistoryValues(Real64 const OldTimeStep, // METHODOLOGY EMPLOYED: // This routine assumes that the direction is to a shorter timestep. // The down step ratio, DSRatio = OldTimeStep/ NewTimeStep - // is expected to be roughly integer-valued and near 2.0 or 3.0 or 4.0 or more. + // is expected to be roughly integer-valued and near 2.0 or 3.0 or 4.0 or more. // first construct data on timestamps for interpolating with later Real64 const oldTime0 = 0.0; @@ -5787,18 +4987,89 @@ void DownInterpolate4HistoryValues(Real64 const OldTimeStep, } } +Real64 DownInterpolate4HistoryValues(Real64 OldTimeStep, Real64 NewTimeStep, std::array const &oldVals, std::array &newVals) +{ + // first construct data on timestamps for interpolating with later + Real64 const oldTime0 = 0.0; + Real64 const oldTime1 = oldTime0 - OldTimeStep; + + Real64 const newTime0 = 0.0; + Real64 const newTime1 = newTime0 - NewTimeStep; + Real64 const newTime2 = newTime1 - NewTimeStep; + Real64 const newTime3 = newTime2 - NewTimeStep; + Real64 const newTime4 = newTime3 - NewTimeStep; + + Real64 const DSRatio = OldTimeStep / NewTimeStep; // should pretty much be an integer value 2, 3, 4, etc. + + if (std::abs(DSRatio - 2.0) < 0.01) { // DSRatio = 2 + // first two points lie between oldVals[0] and oldVals[1] + Real64 delta10 = oldVals[1] - oldVals[0]; + newVals[0] = oldVals[0] + delta10 * ((oldTime0 - newTime1) / OldTimeStep); + newVals[1] = oldVals[0] + delta10 * ((oldTime0 - newTime2) / OldTimeStep); + // last two points lie between oldVals[1] and oldVals[2] + Real64 delta21 = oldVals[2] - oldVals[1]; + newVals[2] = oldVals[1] + delta21 * ((oldTime1 - newTime3) / OldTimeStep); + newVals[3] = oldVals[1] + delta21 * ((oldTime1 - newTime4) / OldTimeStep); + } else if (std::abs(DSRatio - 3.0) < 0.01) { // DSRatio = 3 + // first three points lie between oldVals[0] and oldVals[1] + Real64 delta10 = oldVals[1] - oldVals[0]; + newVals[0] = oldVals[0] + delta10 * ((oldTime0 - newTime1) / OldTimeStep); + newVals[1] = oldVals[0] + delta10 * ((oldTime0 - newTime2) / OldTimeStep); + newVals[2] = oldVals[0] + delta10 * ((oldTime0 - newTime3) / OldTimeStep); + // last point lie between oldVals[1] and oldVals[2] + Real64 delta21 = (oldVals[2] - oldVals[1]) / OldTimeStep; + newVals[3] = oldVals[1] + delta21 * ((oldTime1 - newTime4) / OldTimeStep); + + } else { // DSRatio = 4 or more + // all new points lie between oldVals[0] and oldVals[1] + Real64 delta10 = oldVals[1] - oldVals[0]; + newVals[0] = oldVals[0] + delta10 * ((oldTime0 - newTime1) / OldTimeStep); + newVals[1] = oldVals[0] + delta10 * ((oldTime0 - newTime2) / OldTimeStep); + newVals[2] = oldVals[0] + delta10 * ((oldTime0 - newTime3) / OldTimeStep); + newVals[3] = oldVals[0] + delta10 * ((oldTime0 - newTime4) / OldTimeStep); + } + return oldVals[0]; + + // if (std::abs(DSRatio - 2.0) < 0.01) { // DSRatio = 2 + // // first two points lie between oldVals[0] and oldVals[1] + // Real64 ratio10 = (oldVals[1] - oldVals[0]) / OldTimeStep; + // newVals[0] = oldVals[0] + ratio10 * (oldTime0 - newTime1); + // newVals[1] = oldVals[0] + ratio10 * (oldTime0 - newTime2); + // // last two points lie between oldVals[1] and oldVals[2] + // Real64 ratio21 = (oldVals[2] - oldVals[1]) / OldTimeStep; + // newVals[2] = oldVals[1] + ratio21 * (oldTime1 - newTime3); + // newVals[3] = oldVals[1] + ratio21 * (oldTime1 - newTime4); + // } else if (std::abs(DSRatio - 3.0) < 0.01) { // DSRatio = 3 + // // first three points lie between oldVals[0] and oldVals[1] + // Real64 ratio10 = (oldVals[1] - oldVals[0]) / OldTimeStep; + // newVals[0] = oldVals[0] + ratio10 * (oldTime0 - newTime1); + // newVals[1] = oldVals[0] + ratio10 * (oldTime0 - newTime2); + // newVals[2] = oldVals[0] + ratio10 * (oldTime0 - newTime3); + // // last point lie between oldVals[1] and oldVals[2] + // Real64 ratio21 = (oldVals[2] - oldVals[1]) / OldTimeStep; + // newVals[3] = oldVals[1] + ratio21 * (oldTime1 - newTime4); + + //} else { // DSRatio = 4 or more + // // all new points lie between oldVals[0] and oldVals[1] + // Real64 ratio10 = (oldVals[1] - oldVals[0]) / OldTimeStep; + // newVals[0] = oldVals[0] + ratio10 * (oldTime0 - newTime1); + // newVals[1] = oldVals[0] + ratio10 * (oldTime0 - newTime2); + // newVals[2] = oldVals[0] + ratio10 * (oldTime0 - newTime3); + // newVals[3] = oldVals[0] + ratio10 * (oldTime0 - newTime4); + //} +} void InverseModelTemperature(EnergyPlusData &state, - int const ZoneNum, // Zone number - Real64 &SumIntGain, // Zone sum of convective internal gains - Real64 &SumIntGainExceptPeople, // Zone sum of convective internal gains except for people - Real64 &SumHA, // Zone sum of Hc*Area - Real64 &SumHATsurf, // Zone sum of Hc*Area*Tsurf - Real64 &SumHATref, // Zone sum of Hc*Area*Tref, for ceiling diffuser convection correlation - Real64 &SumMCp, // Zone sum of MassFlowRate*Cp - Real64 &SumMCpT, // Zone sum of MassFlowRate*Cp*T - Real64 &SumSysMCp, // Zone sum of air system MassFlowRate*Cp - Real64 &SumSysMCpT, // Zone sum of air system MassFlowRate*Cp*T - Real64 &AirCap // Formerly CoefAirrat, coef in zone temp eqn with dim of "air power capacity"rd + int const ZoneNum, // Zone number + Real64 const SumIntGain, // Zone sum of convective internal gains + Real64 const SumIntGainExceptPeople, // Zone sum of convective internal gains except for people + Real64 const SumHA, // Zone sum of Hc*Area + Real64 const SumHATsurf, // Zone sum of Hc*Area*Tsurf + Real64 const SumHATref, // Zone sum of Hc*Area*Tref, for ceiling diffuser convection correlation + Real64 const SumMCp, // Zone sum of MassFlowRate*Cp + Real64 const SumMCpT, // Zone sum of MassFlowRate*Cp*T + Real64 const SumSysMCp, // Zone sum of air system MassFlowRate*Cp + Real64 const SumSysMCpT, // Zone sum of air system MassFlowRate*Cp*T + Real64 const AirCap // Formerly CoefAirrat, coef in zone temp eqn with dim of "air power capacity"rd ) { // SUBROUTINE INFORMATION: @@ -5815,46 +5086,44 @@ void InverseModelTemperature(EnergyPlusData &state, Real64 FractionConvection(0.0); // Default convection portion of the sensible heat from people auto &zone = state.dataHeatBal->Zone(ZoneNum); - auto &ZT = state.dataHeatBalFanSys->ZT(ZoneNum); auto &hybridModelZone = state.dataHybridModel->HybridModelZone(ZoneNum); + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); int ZoneMult = zone.Multiplier * zone.ListMultiplier; - zone.ZoneMeasuredTemperature = GetCurrentScheduleValue(state, hybridModelZone.ZoneMeasuredTemperatureSchedulePtr); + zone.ZoneMeasuredTemperature = ScheduleManager::GetCurrentScheduleValue(state, hybridModelZone.ZoneMeasuredTemperatureSchedulePtr); // HM calculation only HM calculation period start if (state.dataEnvrn->DayOfYear >= hybridModelZone.HybridStartDayOfYear && state.dataEnvrn->DayOfYear <= hybridModelZone.HybridEndDayOfYear) { Real64 HMMultiplierAverage(1.0); Real64 MultpHM(1.0); - ZT = zone.ZoneMeasuredTemperature; // Array1D ZT -- Zone - // Air Temperature Averaged over - // the System Time Increment + thisZoneHB.ZT = zone.ZoneMeasuredTemperature; // Array1D ZT -- Zone + // Air Temperature Averaged over + // the System Time Increment if (hybridModelZone.InfiltrationCalc_T && state.dataHVACGlobal->UseZoneTimeStepHistory) { static constexpr std::string_view RoutineNameInfiltration("CalcAirFlowSimple:Infiltration"); if (hybridModelZone.IncludeSystemSupplyParameters) { - zone.ZoneMeasuredSupplyAirTemperature = GetCurrentScheduleValue(state, hybridModelZone.ZoneSupplyAirTemperatureSchedulePtr); - zone.ZoneMeasuredSupplyAirFlowRate = GetCurrentScheduleValue(state, hybridModelZone.ZoneSupplyAirMassFlowRateSchedulePtr); - zone.ZoneMeasuredSupplyAirHumidityRatio = GetCurrentScheduleValue(state, hybridModelZone.ZoneSupplyAirHumidityRatioSchedulePtr); + zone.ZoneMeasuredSupplyAirTemperature = + ScheduleManager::GetCurrentScheduleValue(state, hybridModelZone.ZoneSupplyAirTemperatureSchedulePtr); + zone.ZoneMeasuredSupplyAirFlowRate = + ScheduleManager::GetCurrentScheduleValue(state, hybridModelZone.ZoneSupplyAirMassFlowRateSchedulePtr); + zone.ZoneMeasuredSupplyAirHumidityRatio = + ScheduleManager::GetCurrentScheduleValue(state, hybridModelZone.ZoneSupplyAirHumidityRatioSchedulePtr); // Calculate the air humidity ratio at supply air inlet. Real64 CpAirInlet(0.0); - CpAirInlet = PsyCpAirFnW(zone.ZoneMeasuredSupplyAirHumidityRatio); + CpAirInlet = Psychrometrics::PsyCpAirFnW(zone.ZoneMeasuredSupplyAirHumidityRatio); Real64 SumSysMCp_HM = zone.ZoneMeasuredSupplyAirFlowRate * CpAirInlet; Real64 SumSysMCpT_HM = zone.ZoneMeasuredSupplyAirFlowRate * CpAirInlet * zone.ZoneMeasuredSupplyAirTemperature; - AA = SumSysMCp_HM + SumHA + state.dataHeatBalFanSys->MCPV(ZoneNum) + state.dataHeatBalFanSys->MCPM(ZoneNum) + - state.dataHeatBalFanSys->MCPE(ZoneNum) + state.dataHeatBalFanSys->MCPC(ZoneNum) + state.dataHeatBalFanSys->MDotCPOA(ZoneNum); - BB = SumSysMCpT_HM + SumIntGain + SumHATsurf - SumHATref + state.dataHeatBalFanSys->MCPTV(ZoneNum) + - state.dataHeatBalFanSys->MCPTM(ZoneNum) + state.dataHeatBalFanSys->MCPTE(ZoneNum) + state.dataHeatBalFanSys->MCPTC(ZoneNum) + - state.dataHeatBalFanSys->MDotCPOA(ZoneNum) * zone.OutDryBulbTemp + - (state.dataHeatBalFanSys->NonAirSystemResponse(ZoneNum) / ZoneMult + state.dataHeatBalFanSys->SysDepZoneLoadsLagged(ZoneNum)); + AA = SumSysMCp_HM + SumHA + thisZoneHB.MCPV + thisZoneHB.MCPM + thisZoneHB.MCPE + thisZoneHB.MCPC + thisZoneHB.MDotCPOA; + BB = SumSysMCpT_HM + SumIntGain + SumHATsurf - SumHATref + thisZoneHB.MCPTV + thisZoneHB.MCPTM + thisZoneHB.MCPTE + thisZoneHB.MCPTC + + thisZoneHB.MDotCPOA * zone.OutDryBulbTemp + (thisZoneHB.NonAirSystemResponse / ZoneMult + thisZoneHB.SysDepZoneLoadsLagged); } else { - AA = SumHA + state.dataHeatBalFanSys->MCPV(ZoneNum) + state.dataHeatBalFanSys->MCPM(ZoneNum) + - state.dataHeatBalFanSys->MCPE(ZoneNum) + state.dataHeatBalFanSys->MCPC(ZoneNum) + state.dataHeatBalFanSys->MDotCPOA(ZoneNum); - BB = SumIntGain + SumHATsurf - SumHATref + state.dataHeatBalFanSys->MCPTV(ZoneNum) + state.dataHeatBalFanSys->MCPTM(ZoneNum) + - state.dataHeatBalFanSys->MCPTE(ZoneNum) + state.dataHeatBalFanSys->MCPTC(ZoneNum) + - state.dataHeatBalFanSys->MDotCPOA(ZoneNum) * zone.OutDryBulbTemp; + AA = SumHA + thisZoneHB.MCPV + thisZoneHB.MCPM + thisZoneHB.MCPE + thisZoneHB.MCPC + thisZoneHB.MDotCPOA; + BB = SumIntGain + SumHATsurf - SumHATref + thisZoneHB.MCPTV + thisZoneHB.MCPTM + thisZoneHB.MCPTE + thisZoneHB.MCPTC + + thisZoneHB.MDotCPOA * zone.OutDryBulbTemp; } Real64 CC = AirCap; Real64 DD = @@ -5862,9 +5131,9 @@ void InverseModelTemperature(EnergyPlusData &state, (1.0 / 3.0) * state.dataHeatBalFanSys->PreviousMeasuredZT3(ZoneNum)); Real64 delta_T = (zone.ZoneMeasuredTemperature - zone.OutDryBulbTemp); - Real64 CpAir = PsyCpAirFnW(state.dataEnvrn->OutHumRat); - Real64 AirDensity = - PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, zone.OutDryBulbTemp, state.dataEnvrn->OutHumRat, RoutineNameInfiltration); + Real64 CpAir = Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat); + Real64 AirDensity = Psychrometrics::PsyRhoAirFnPbTdbW( + state, state.dataEnvrn->OutBaroPress, zone.OutDryBulbTemp, state.dataEnvrn->OutHumRat, RoutineNameInfiltration); zone.delta_T = delta_T; // s4 - Set ACH to 0 when delta_T <= 0.5, add max and min limits to ach @@ -5882,13 +5151,12 @@ void InverseModelTemperature(EnergyPlusData &state, } // Hybrid model infiltration calculation end // Hybrid modeling internal thermal mass calculation start - if (hybridModelZone.InternalThermalMassCalc_T && SumSysMCpT == 0 && ZT != state.dataHeatBalFanSys->PreviousMeasuredZT1(ZoneNum) && + if (hybridModelZone.InternalThermalMassCalc_T && SumSysMCpT == 0 && thisZoneHB.ZT != state.dataHeatBalFanSys->PreviousMeasuredZT1(ZoneNum) && state.dataHVACGlobal->UseZoneTimeStepHistory) { // HM calculation only when SumSysMCpT =0, // TimeStepZone (not @ TimeStepSys) Real64 TempDepCoef = SumHA + SumMCp + SumSysMCp; - Real64 TempIndCoef = - SumIntGain + SumHATsurf - SumHATref + SumMCpT + SumSysMCpT + - (state.dataHeatBalFanSys->NonAirSystemResponse(ZoneNum) / ZoneMult + state.dataHeatBalFanSys->SysDepZoneLoadsLagged(ZoneNum)); + Real64 TempIndCoef = SumIntGain + SumHATsurf - SumHATref + SumMCpT + SumSysMCpT + + (thisZoneHB.NonAirSystemResponse / ZoneMult + thisZoneHB.SysDepZoneLoadsLagged); // TempHistoryTerm = AirCap * (3.0 * ZTM1(ZoneNum) - (3.0/2.0) * ZTM2(ZoneNum) + (1.0/3.0) * ZTM3(ZoneNum)) !debug only if (state.afn->distribution_simulated) { @@ -5896,34 +5164,34 @@ void InverseModelTemperature(EnergyPlusData &state, } // Calculate air capacity using DataHeatBalance::SolutionAlgo::AnalyticalSolution if (TempDepCoef == 0.0) { - // Is this correct? Shouldn't we use log?? What if ZT(ZoneNum) == + // Is this correct? Shouldn't we use log?? What if thisZT == // PreviousMeasuredZT1(ZoneNum)?? - AirCapHM = TempIndCoef / (ZT - state.dataHeatBalFanSys->PreviousMeasuredZT1(ZoneNum)); // Inverse equation + AirCapHM = TempIndCoef / (thisZoneHB.ZT - state.dataHeatBalFanSys->PreviousMeasuredZT1(ZoneNum)); // Inverse equation } else { Real64 AirCapHM_temp = 0.0; - if (TempIndCoef == TempDepCoef * ZT) { + if (TempIndCoef == TempDepCoef * thisZoneHB.ZT) { AirCapHM_temp = 0.0; // This is the denominator. } else { - AirCapHM_temp = - (TempIndCoef - TempDepCoef * state.dataHeatBalFanSys->PreviousMeasuredZT1(ZoneNum)) / (TempIndCoef - TempDepCoef * ZT); + AirCapHM_temp = (TempIndCoef - TempDepCoef * state.dataHeatBalFanSys->PreviousMeasuredZT1(ZoneNum)) / + (TempIndCoef - TempDepCoef * thisZoneHB.ZT); } if ((AirCapHM_temp > 0) && (AirCapHM_temp != 1)) { // Avoide IND AirCapHM = TempDepCoef / std::log(AirCapHM_temp); // Inverse equation } else { - AirCapHM = TempIndCoef / (ZT - state.dataHeatBalFanSys->PreviousMeasuredZT1(ZoneNum)); + AirCapHM = TempIndCoef / (thisZoneHB.ZT - state.dataHeatBalFanSys->PreviousMeasuredZT1(ZoneNum)); } } // Calculate multiplier - if (std::abs(ZT - state.dataHeatBalFanSys->PreviousMeasuredZT1(ZoneNum)) > 0.05) { // Filter + if (std::abs(thisZoneHB.ZT - state.dataHeatBalFanSys->PreviousMeasuredZT1(ZoneNum)) > 0.05) { // Filter MultpHM = AirCapHM / (zone.Volume * - PsyRhoAirFnPbTdbW(state, - state.dataEnvrn->OutBaroPress, - ZT, - state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)) * - PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum))) * + Psychrometrics::PsyRhoAirFnPbTdbW(state, + state.dataEnvrn->OutBaroPress, + thisZoneHB.ZT, + thisZoneHB.ZoneAirHumRat) * + Psychrometrics::PsyCpAirFnW(thisZoneHB.ZoneAirHumRat)) * (state.dataGlobal->TimeStepZone * DataGlobalConstants::SecInHour); // Inverse equation if ((MultpHM < 1.0) || (MultpHM > 30.0)) { // Temperature capacity multiplier greater than // 1 and less than 30 @@ -5954,14 +5222,16 @@ void InverseModelTemperature(EnergyPlusData &state, // Hybrid model people count calculation if (hybridModelZone.PeopleCountCalc_T && state.dataHVACGlobal->UseZoneTimeStepHistory) { - zone.ZoneMeasuredTemperature = GetCurrentScheduleValue(state, hybridModelZone.ZoneMeasuredTemperatureSchedulePtr); - zone.ZonePeopleActivityLevel = GetCurrentScheduleValue(state, hybridModelZone.ZonePeopleActivityLevelSchedulePtr); - zone.ZonePeopleSensibleHeatFraction = GetCurrentScheduleValue(state, hybridModelZone.ZonePeopleSensibleFractionSchedulePtr); - zone.ZonePeopleRadiantHeatFraction = GetCurrentScheduleValue(state, hybridModelZone.ZonePeopleRadiationFractionSchedulePtr); + zone.ZoneMeasuredTemperature = ScheduleManager::GetCurrentScheduleValue(state, hybridModelZone.ZoneMeasuredTemperatureSchedulePtr); + zone.ZonePeopleActivityLevel = ScheduleManager::GetCurrentScheduleValue(state, hybridModelZone.ZonePeopleActivityLevelSchedulePtr); + zone.ZonePeopleSensibleHeatFraction = + ScheduleManager::GetCurrentScheduleValue(state, hybridModelZone.ZonePeopleSensibleFractionSchedulePtr); + zone.ZonePeopleRadiantHeatFraction = + ScheduleManager::GetCurrentScheduleValue(state, hybridModelZone.ZonePeopleRadiationFractionSchedulePtr); Real64 FractionSensible = zone.ZonePeopleSensibleHeatFraction; Real64 FractionRadiation = zone.ZonePeopleRadiantHeatFraction; - Real64 ActivityLevel = GetCurrentScheduleValue(state, hybridModelZone.ZonePeopleActivityLevelSchedulePtr); + Real64 ActivityLevel = ScheduleManager::GetCurrentScheduleValue(state, hybridModelZone.ZonePeopleActivityLevelSchedulePtr); if (FractionSensible <= 0.0) { FractionSensible = 0.6; @@ -5978,19 +5248,22 @@ void InverseModelTemperature(EnergyPlusData &state, } if (hybridModelZone.IncludeSystemSupplyParameters) { - zone.ZoneMeasuredSupplyAirTemperature = GetCurrentScheduleValue(state, hybridModelZone.ZoneSupplyAirTemperatureSchedulePtr); - zone.ZoneMeasuredSupplyAirFlowRate = GetCurrentScheduleValue(state, hybridModelZone.ZoneSupplyAirMassFlowRateSchedulePtr); - zone.ZoneMeasuredSupplyAirHumidityRatio = GetCurrentScheduleValue(state, hybridModelZone.ZoneSupplyAirHumidityRatioSchedulePtr); + zone.ZoneMeasuredSupplyAirTemperature = + ScheduleManager::GetCurrentScheduleValue(state, hybridModelZone.ZoneSupplyAirTemperatureSchedulePtr); + zone.ZoneMeasuredSupplyAirFlowRate = + ScheduleManager::GetCurrentScheduleValue(state, hybridModelZone.ZoneSupplyAirMassFlowRateSchedulePtr); + zone.ZoneMeasuredSupplyAirHumidityRatio = + ScheduleManager::GetCurrentScheduleValue(state, hybridModelZone.ZoneSupplyAirHumidityRatioSchedulePtr); // Calculate the air humidity ratio at supply air inlet. - Real64 CpAirInlet = PsyCpAirFnW(zone.ZoneMeasuredSupplyAirHumidityRatio); + Real64 CpAirInlet = Psychrometrics::PsyCpAirFnW(zone.ZoneMeasuredSupplyAirHumidityRatio); Real64 SumSysMCp_HM = zone.ZoneMeasuredSupplyAirFlowRate * CpAirInlet; Real64 SumSysMCpT_HM = zone.ZoneMeasuredSupplyAirFlowRate * CpAirInlet * zone.ZoneMeasuredSupplyAirTemperature; AA = SumSysMCp_HM + SumHA + SumMCp; BB = SumSysMCpT_HM + SumIntGainExceptPeople + SumHATsurf - SumHATref + SumMCpT + - (state.dataHeatBalFanSys->NonAirSystemResponse(ZoneNum) / ZoneMult + state.dataHeatBalFanSys->SysDepZoneLoadsLagged(ZoneNum)); + (thisZoneHB.NonAirSystemResponse / ZoneMult + thisZoneHB.SysDepZoneLoadsLagged); } else { AA = SumHA + SumMCp; BB = SumIntGainExceptPeople + SumHATsurf - SumHATref + SumMCpT; @@ -6015,17 +5288,17 @@ void InverseModelTemperature(EnergyPlusData &state, // Update zone temperatures in the previous steps state.dataHeatBalFanSys->PreviousMeasuredZT3(ZoneNum) = state.dataHeatBalFanSys->PreviousMeasuredZT2(ZoneNum); state.dataHeatBalFanSys->PreviousMeasuredZT2(ZoneNum) = state.dataHeatBalFanSys->PreviousMeasuredZT1(ZoneNum); - state.dataHeatBalFanSys->PreviousMeasuredZT1(ZoneNum) = ZT; + state.dataHeatBalFanSys->PreviousMeasuredZT1(ZoneNum) = thisZoneHB.ZT; } void InverseModelHumidity(EnergyPlusData &state, - int const ZoneNum, // Zone number - Real64 &LatentGain, // Zone sum of latent gain - Real64 &LatentGainExceptPeople, // Zone sum of latent gain except for people - Real64 &ZoneMassFlowRate, // Zone air mass flow rate - Real64 &MoistureMassFlowRate, // Zone moisture mass flow rate - Real64 &H2OHtOfVap, // Heat of vaporization of air - Real64 &RhoAir // Air density + int const ZoneNum, // Zone number + Real64 const LatentGain, // Zone sum of latent gain + Real64 const LatentGainExceptPeople, // Zone sum of latent gain except for people + Real64 const ZoneMassFlowRate, // Zone air mass flow rate + Real64 const MoistureMassFlowRate, // Zone moisture mass flow rate + Real64 const H2OHtOfVap, // Heat of vaporization of air + Real64 const RhoAir // Air density ) { // SUBROUTINE INFORMATION: @@ -6046,38 +5319,35 @@ void InverseModelHumidity(EnergyPlusData &state, auto &zone = state.dataHeatBal->Zone(ZoneNum); auto &hybridModelZone = state.dataHybridModel->HybridModelZone(ZoneNum); + auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); // Get measured zone humidity ratio - zone.ZoneMeasuredHumidityRatio = GetCurrentScheduleValue(state, hybridModelZone.ZoneMeasuredHumidityRatioSchedulePtr); + zone.ZoneMeasuredHumidityRatio = ScheduleManager::GetCurrentScheduleValue(state, hybridModelZone.ZoneMeasuredHumidityRatioSchedulePtr); if (state.dataEnvrn->DayOfYear >= hybridModelZone.HybridStartDayOfYear && state.dataEnvrn->DayOfYear <= hybridModelZone.HybridEndDayOfYear) { - state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum) = zone.ZoneMeasuredHumidityRatio; + thisZoneHB.ZoneAirHumRat = zone.ZoneMeasuredHumidityRatio; // Hybrid Model calculate air infiltration rate if (hybridModelZone.InfiltrationCalc_H && state.dataHVACGlobal->UseZoneTimeStepHistory) { // Conditionally calculate the time dependent and time independent terms if (hybridModelZone.IncludeSystemSupplyParameters) { - zone.ZoneMeasuredSupplyAirFlowRate = GetCurrentScheduleValue(state, hybridModelZone.ZoneSupplyAirMassFlowRateSchedulePtr); - zone.ZoneMeasuredSupplyAirHumidityRatio = GetCurrentScheduleValue(state, hybridModelZone.ZoneSupplyAirHumidityRatioSchedulePtr); + zone.ZoneMeasuredSupplyAirFlowRate = + ScheduleManager::GetCurrentScheduleValue(state, hybridModelZone.ZoneSupplyAirMassFlowRateSchedulePtr); + zone.ZoneMeasuredSupplyAirHumidityRatio = + ScheduleManager::GetCurrentScheduleValue(state, hybridModelZone.ZoneSupplyAirHumidityRatioSchedulePtr); Real64 SumSysM_HM = zone.ZoneMeasuredSupplyAirFlowRate; Real64 SumSysMHumRat_HM = zone.ZoneMeasuredSupplyAirFlowRate * zone.ZoneMeasuredSupplyAirHumidityRatio; - AA = SumSysM_HM + state.dataHeatBalFanSys->VAMFL(ZoneNum) + state.dataHeatBalFanSys->EAMFL(ZoneNum) + - state.dataHeatBalFanSys->CTMFL(ZoneNum) + state.dataHeatBalFanSys->SumHmARa(ZoneNum) + - state.dataHeatBalFanSys->MixingMassFlowZone(ZoneNum) + state.dataHeatBalFanSys->MDotOA(ZoneNum); - BB = SumSysMHumRat_HM + (LatentGain / H2OHtOfVap) + - ((state.dataHeatBalFanSys->VAMFL(ZoneNum) + state.dataHeatBalFanSys->CTMFL(ZoneNum)) * state.dataEnvrn->OutHumRat) + - state.dataHeatBalFanSys->EAMFLxHumRat(ZoneNum) + state.dataHeatBalFanSys->SumHmARaW(ZoneNum) + - state.dataHeatBalFanSys->MixingMassFlowXHumRat(ZoneNum) + state.dataHeatBalFanSys->MDotOA(ZoneNum) * state.dataEnvrn->OutHumRat; + AA = SumSysM_HM + thisZoneHB.VAMFL + thisZoneHB.EAMFL + thisZoneHB.CTMFL + thisZoneHB.SumHmARa + thisZoneHB.MixingMassFlowZone + + thisZoneHB.MDotOA; + BB = SumSysMHumRat_HM + (LatentGain / H2OHtOfVap) + ((thisZoneHB.VAMFL + thisZoneHB.CTMFL) * state.dataEnvrn->OutHumRat) + + thisZoneHB.EAMFLxHumRat + thisZoneHB.SumHmARaW + thisZoneHB.MixingMassFlowXHumRat + + thisZoneHB.MDotOA * state.dataEnvrn->OutHumRat; } else { - AA = state.dataHeatBalFanSys->VAMFL(ZoneNum) + state.dataHeatBalFanSys->EAMFL(ZoneNum) + state.dataHeatBalFanSys->CTMFL(ZoneNum) + - state.dataHeatBalFanSys->SumHmARa(ZoneNum) + state.dataHeatBalFanSys->MixingMassFlowZone(ZoneNum) + - state.dataHeatBalFanSys->MDotOA(ZoneNum); - BB = (LatentGain / H2OHtOfVap) + - ((state.dataHeatBalFanSys->VAMFL(ZoneNum) + state.dataHeatBalFanSys->CTMFL(ZoneNum)) * state.dataEnvrn->OutHumRat) + - state.dataHeatBalFanSys->EAMFLxHumRat(ZoneNum) + state.dataHeatBalFanSys->SumHmARaW(ZoneNum) + - state.dataHeatBalFanSys->MixingMassFlowXHumRat(ZoneNum) + state.dataHeatBalFanSys->MDotOA(ZoneNum) * state.dataEnvrn->OutHumRat; + AA = thisZoneHB.VAMFL + thisZoneHB.EAMFL + thisZoneHB.CTMFL + thisZoneHB.SumHmARa + thisZoneHB.MixingMassFlowZone + thisZoneHB.MDotOA; + BB = (LatentGain / H2OHtOfVap) + ((thisZoneHB.VAMFL + thisZoneHB.CTMFL) * state.dataEnvrn->OutHumRat) + thisZoneHB.EAMFLxHumRat + + thisZoneHB.SumHmARaW + thisZoneHB.MixingMassFlowXHumRat + thisZoneHB.MDotOA * state.dataEnvrn->OutHumRat; } Real64 CC = RhoAir * zone.Volume * zone.ZoneVolCapMultpMoist / SysTimeStepInSeconds; @@ -6087,7 +5357,8 @@ void InverseModelHumidity(EnergyPlusData &state, Real64 delta_HR = (zone.ZoneMeasuredHumidityRatio - state.dataEnvrn->OutHumRat); - Real64 AirDensity = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, zone.OutDryBulbTemp, state.dataEnvrn->OutHumRat, RoutineName); + Real64 AirDensity = + Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, zone.OutDryBulbTemp, state.dataEnvrn->OutHumRat, RoutineName); Real64 M_inf = 0.0; if (std::abs(zone.ZoneMeasuredHumidityRatio - state.dataEnvrn->OutHumRat) > 0.0000001) { @@ -6103,9 +5374,11 @@ void InverseModelHumidity(EnergyPlusData &state, // Hybrid Model calculate people count if (hybridModelZone.PeopleCountCalc_H && state.dataHVACGlobal->UseZoneTimeStepHistory) { - zone.ZonePeopleActivityLevel = GetCurrentScheduleValue(state, hybridModelZone.ZonePeopleActivityLevelSchedulePtr); - zone.ZonePeopleSensibleHeatFraction = GetCurrentScheduleValue(state, hybridModelZone.ZonePeopleSensibleFractionSchedulePtr); - zone.ZonePeopleRadiantHeatFraction = GetCurrentScheduleValue(state, hybridModelZone.ZonePeopleRadiationFractionSchedulePtr); + zone.ZonePeopleActivityLevel = ScheduleManager::GetCurrentScheduleValue(state, hybridModelZone.ZonePeopleActivityLevelSchedulePtr); + zone.ZonePeopleSensibleHeatFraction = + ScheduleManager::GetCurrentScheduleValue(state, hybridModelZone.ZonePeopleSensibleFractionSchedulePtr); + zone.ZonePeopleRadiantHeatFraction = + ScheduleManager::GetCurrentScheduleValue(state, hybridModelZone.ZonePeopleRadiationFractionSchedulePtr); Real64 FractionSensible = zone.ZonePeopleSensibleHeatFraction; @@ -6120,29 +5393,25 @@ void InverseModelHumidity(EnergyPlusData &state, // Conditionally calculate the humidity-dependent and humidity-independent // terms. if (hybridModelZone.IncludeSystemSupplyParameters) { - zone.ZoneMeasuredSupplyAirFlowRate = GetCurrentScheduleValue(state, hybridModelZone.ZoneSupplyAirMassFlowRateSchedulePtr); - zone.ZoneMeasuredSupplyAirHumidityRatio = GetCurrentScheduleValue(state, hybridModelZone.ZoneSupplyAirHumidityRatioSchedulePtr); + zone.ZoneMeasuredSupplyAirFlowRate = + ScheduleManager::GetCurrentScheduleValue(state, hybridModelZone.ZoneSupplyAirMassFlowRateSchedulePtr); + zone.ZoneMeasuredSupplyAirHumidityRatio = + ScheduleManager::GetCurrentScheduleValue(state, hybridModelZone.ZoneSupplyAirHumidityRatioSchedulePtr); Real64 SumSysM_HM = zone.ZoneMeasuredSupplyAirFlowRate; Real64 SumSysMHumRat_HM = zone.ZoneMeasuredSupplyAirFlowRate * zone.ZoneMeasuredSupplyAirHumidityRatio; - AA = SumSysM_HM + state.dataHeatBalFanSys->OAMFL(ZoneNum) + state.dataHeatBalFanSys->VAMFL(ZoneNum) + - state.dataHeatBalFanSys->EAMFL(ZoneNum) + state.dataHeatBalFanSys->CTMFL(ZoneNum) + state.dataHeatBalFanSys->SumHmARa(ZoneNum) + - state.dataHeatBalFanSys->MixingMassFlowZone(ZoneNum) + state.dataHeatBalFanSys->MDotOA(ZoneNum); + AA = SumSysM_HM + thisZoneHB.OAMFL + thisZoneHB.VAMFL + thisZoneHB.EAMFL + thisZoneHB.CTMFL + thisZoneHB.SumHmARa + + thisZoneHB.MixingMassFlowZone + thisZoneHB.MDotOA; BB = SumSysMHumRat_HM + (LatentGainExceptPeople / H2OHtOfVap) + - ((state.dataHeatBalFanSys->OAMFL(ZoneNum) + state.dataHeatBalFanSys->VAMFL(ZoneNum) + state.dataHeatBalFanSys->CTMFL(ZoneNum)) * - state.dataEnvrn->OutHumRat) + - state.dataHeatBalFanSys->EAMFLxHumRat(ZoneNum) + state.dataHeatBalFanSys->SumHmARaW(ZoneNum) + - state.dataHeatBalFanSys->MixingMassFlowXHumRat(ZoneNum) + state.dataHeatBalFanSys->MDotOA(ZoneNum) * state.dataEnvrn->OutHumRat; + ((thisZoneHB.OAMFL + thisZoneHB.VAMFL + thisZoneHB.CTMFL) * state.dataEnvrn->OutHumRat) + thisZoneHB.EAMFLxHumRat + + thisZoneHB.SumHmARaW + thisZoneHB.MixingMassFlowXHumRat + thisZoneHB.MDotOA * state.dataEnvrn->OutHumRat; } else { - AA = ZoneMassFlowRate + state.dataHeatBalFanSys->OAMFL(ZoneNum) + state.dataHeatBalFanSys->VAMFL(ZoneNum) + - state.dataHeatBalFanSys->EAMFL(ZoneNum) + state.dataHeatBalFanSys->CTMFL(ZoneNum) + state.dataHeatBalFanSys->SumHmARa(ZoneNum) + - state.dataHeatBalFanSys->MixingMassFlowZone(ZoneNum) + state.dataHeatBalFanSys->MDotOA(ZoneNum); - BB = (LatentGainExceptPeople / H2OHtOfVap) + - ((state.dataHeatBalFanSys->OAMFL(ZoneNum) + state.dataHeatBalFanSys->VAMFL(ZoneNum) + state.dataHeatBalFanSys->CTMFL(ZoneNum)) * - state.dataEnvrn->OutHumRat) + - state.dataHeatBalFanSys->EAMFLxHumRat(ZoneNum) + (MoistureMassFlowRate) + state.dataHeatBalFanSys->SumHmARaW(ZoneNum) + - state.dataHeatBalFanSys->MixingMassFlowXHumRat(ZoneNum) + state.dataHeatBalFanSys->MDotOA(ZoneNum) * state.dataEnvrn->OutHumRat; + AA = ZoneMassFlowRate + thisZoneHB.OAMFL + thisZoneHB.VAMFL + thisZoneHB.EAMFL + thisZoneHB.CTMFL + thisZoneHB.SumHmARa + + thisZoneHB.MixingMassFlowZone + thisZoneHB.MDotOA; + BB = (LatentGainExceptPeople / H2OHtOfVap) + ((thisZoneHB.OAMFL + thisZoneHB.VAMFL + thisZoneHB.CTMFL) * state.dataEnvrn->OutHumRat) + + thisZoneHB.EAMFLxHumRat + (MoistureMassFlowRate) + thisZoneHB.SumHmARaW + thisZoneHB.MixingMassFlowXHumRat + + thisZoneHB.MDotOA * state.dataEnvrn->OutHumRat; } Real64 CC = RhoAir * zone.Volume * zone.ZoneVolCapMultpMoist / SysTimeStepInSeconds; @@ -6167,28 +5436,21 @@ void InverseModelHumidity(EnergyPlusData &state, state.dataHeatBalFanSys->PreviousMeasuredHumRat1(ZoneNum) = zone.ZoneMeasuredHumidityRatio; } -void CalcZoneSums(EnergyPlusData &state, - int const ZoneNum, // Zone number - Real64 &SumIntGain, // Zone sum of convective internal gains - Real64 &SumHA, // Zone sum of Hc*Area - Real64 &SumHATsurf, // Zone sum of Hc*Area*Tsurf - Real64 &SumHATref, // Zone sum of Hc*Area*Tref, for ceiling diffuser convection correlation - Real64 &SumMCp, // Zone sum of MassFlowRate*Cp - Real64 &SumMCpT, // Zone sum of MassFlowRate*Cp*T - Real64 &SumSysMCp, // Zone sum of air system MassFlowRate*Cp - Real64 &SumSysMCpT, // Zone sum of air system MassFlowRate*Cp*T - bool const CorrectorFlag) +void ZoneSpaceHeatBalanceData::calcZoneOrSpaceSums(EnergyPlusData &state, + bool const CorrectorFlag, // Corrector call flag + int const zoneNum, + int const spaceNum) { // SUBROUTINE INFORMATION: // AUTHOR Peter Graham Ellis // DATE WRITTEN July 2003 - // MODIFIED Aug 2003, FCW: add SumHA contributions from window frame and divider + // MODIFIED Aug 2003, FCW: add this->SumHA contributions from window frame and divider // Aug 2003, CC: change how the reference temperatures are used // PURPOSE OF THIS SUBROUTINE: // This subroutine calculates the various sums that go into the zone heat balance - // equation. This replaces the SUMC, SUMHA, and SUMHAT calculations that were + // equation. This replaces the SUMC, SumHA, and SumHAT calculations that were // previously done in various places throughout the program. // The SumHAT portion of the code is reproduced in RadiantSystemHighTemp and // RadiantSystemLowTemp and should be updated accordingly. @@ -6199,101 +5461,143 @@ void CalcZoneSums(EnergyPlusData &state, // If Tref is not used at all, SumHATref = 0, and SumHA /= 0. // For future implementations, Tref can be easily converted into an array to // allow a different reference temperature to be specified for each surface. - - SumHA = 0.0; - SumHATsurf = 0.0; - SumHATref = 0.0; - SumSysMCp = 0.0; - SumSysMCpT = 0.0; - // Sum all convective internal gains: SumIntGain - SumIntGain = InternalHeatGains::SumAllInternalConvectionGains(state, ZoneNum); - SumIntGain += state.dataHeatBalFanSys->SumConvHTRadSys(ZoneNum) + state.dataHeatBalFanSys->SumConvPool(ZoneNum); + assert(zoneNum > 0); + + this->SumHA = 0.0; + this->SumHATsurf = 0.0; + this->SumHATref = 0.0; + this->SumSysMCp = 0.0; + this->SumSysMCpT = 0.0; + // Sum all convective internal gains: this->SumIntGain + if (spaceNum == 0) { + this->SumIntGain = InternalHeatGains::zoneSumAllInternalConvectionGains(state, zoneNum); + } else { + this->SumIntGain = InternalHeatGains::spaceSumAllInternalConvectionGains(state, spaceNum); + } + this->SumIntGain += state.dataHeatBalFanSys->SumConvHTRadSys(zoneNum) + state.dataHeatBalFanSys->SumConvPool(zoneNum); // Add heat to return air if zonal system (no return air) or cycling system (return air frequently very low or zero) - auto &zone = state.dataHeatBal->Zone(ZoneNum); - if (zone.NoHeatToReturnAir) { - SumIntGain += InternalHeatGains::SumAllReturnAirConvectionGains(state, ZoneNum, 0); + assert(zoneNum > 0); + auto &thisZone = state.dataHeatBal->Zone(zoneNum); + if (thisZone.NoHeatToReturnAir) { + if (spaceNum == 0) { + this->SumIntGain += InternalHeatGains::zoneSumAllReturnAirConvectionGains(state, zoneNum, 0); + } else { + this->SumIntGain += InternalHeatGains::spaceSumAllReturnAirConvectionGains(state, spaceNum, 0); + } } - // Sum all non-system air flow, i.e. infiltration, simple ventilation, mixing, earth tube: SumMCp, SumMCpT - SumMCp = state.dataHeatBalFanSys->MCPI(ZoneNum) + state.dataHeatBalFanSys->MCPV(ZoneNum) + state.dataHeatBalFanSys->MCPM(ZoneNum) + - state.dataHeatBalFanSys->MCPE(ZoneNum) + state.dataHeatBalFanSys->MCPC(ZoneNum) + state.dataHeatBalFanSys->MDotCPOA(ZoneNum); - SumMCpT = state.dataHeatBalFanSys->MCPTI(ZoneNum) + state.dataHeatBalFanSys->MCPTV(ZoneNum) + state.dataHeatBalFanSys->MCPTM(ZoneNum) + - state.dataHeatBalFanSys->MCPTE(ZoneNum) + state.dataHeatBalFanSys->MCPTC(ZoneNum) + - state.dataHeatBalFanSys->MDotCPOA(ZoneNum) * zone.OutDryBulbTemp; + // Sum all non-system air flow, i.e. infiltration, simple ventilation, mixing, earth tube: this->SumMCp, this->SumMCpT + this->SumMCp = this->MCPI + this->MCPV + this->MCPM + this->MCPE + this->MCPC + this->MDotCPOA; + this->SumMCpT = this->MCPTI + this->MCPTV + this->MCPTM + this->MCPTE + this->MCPTC + this->MDotCPOA * thisZone.OutDryBulbTemp; // Sum all multizone air flow calculated from AirflowNetwork by assuming no simple air infiltration model if (state.afn->multizone_always_simulated || (state.afn->simulation_control.type == AirflowNetwork::ControlType::MultizoneWithDistributionOnlyDuringFanOperation && state.afn->AirflowNetworkFanActivated)) { - auto &exchangeData = state.afn->exchangeData(ZoneNum); - SumMCp = exchangeData.SumMCp + exchangeData.SumMVCp + exchangeData.SumMMCp; - SumMCpT = exchangeData.SumMCpT + exchangeData.SumMVCpT + exchangeData.SumMMCpT; + auto &exchangeData = state.afn->exchangeData(zoneNum); + this->SumMCp = exchangeData.SumMCp + exchangeData.SumMVCp + exchangeData.SumMMCp; + this->SumMCpT = exchangeData.SumMCpT + exchangeData.SumMVCpT + exchangeData.SumMMCpT; } - // Sum all system air flow: SumSysMCp, SumSysMCpT and check to see if this is a controlled zone - bool ControlledZoneAirFlag = zone.IsControlled; + // Sum all system air flow: this->SumSysMCp, this->SumSysMCpT and check to see if this is a controlled zone if (CorrectorFlag) { - // Check to see if this is a plenum zone - bool ZoneRetPlenumAirFlag = zone.IsReturnPlenum; - bool ZoneSupPlenumAirFlag = zone.IsSupplyPlenum; - // Plenum and controlled zones have a different set of inlet nodes which must be calculated. - if (ControlledZoneAirFlag) { - auto const &zec(state.dataZoneEquip->ZoneEquipConfig(ZoneNum)); + if (thisZone.IsControlled) { + auto const &zec(state.dataZoneEquip->ZoneEquipConfig(zoneNum)); for (int NodeNum = 1, NodeNum_end = zec.NumInletNodes; NodeNum <= NodeNum_end; ++NodeNum) { // Get node conditions, this next block is of interest to irratic system loads... maybe nodes are not accurate at time of call? // how can we tell? predict step must be lagged ? correct step, systems have run. auto const &node(state.dataLoopNodes->Node(zec.InletNode(NodeNum))); - Real64 CpAir = PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)); + Real64 CpAir = Psychrometrics::PsyCpAirFnW(this->ZoneAirHumRat); Real64 const MassFlowRate_CpAir(node.MassFlowRate * CpAir); - SumSysMCp += MassFlowRate_CpAir; - SumSysMCpT += MassFlowRate_CpAir * node.Temp; + this->SumSysMCp += MassFlowRate_CpAir; + this->SumSysMCpT += MassFlowRate_CpAir * node.Temp; } - } else if (ZoneRetPlenumAirFlag) { - auto const &zrpc(state.dataZonePlenum->ZoneRetPlenCond(zone.PlenumCondNum)); - Real64 const air_hum_rat(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)); + } else if (thisZone.IsReturnPlenum) { + auto const &zrpc(state.dataZonePlenum->ZoneRetPlenCond(thisZone.PlenumCondNum)); + Real64 const air_hum_rat(this->ZoneAirHumRat); for (int NodeNum = 1, NodeNum_end = zrpc.NumInletNodes; NodeNum <= NodeNum_end; ++NodeNum) { auto const &node(state.dataLoopNodes->Node(zrpc.InletNode(NodeNum))); - Real64 const MassFlowRate_CpAir(node.MassFlowRate * PsyCpAirFnW(air_hum_rat)); - SumSysMCp += MassFlowRate_CpAir; - SumSysMCpT += MassFlowRate_CpAir * node.Temp; + Real64 const MassFlowRate_CpAir(node.MassFlowRate * Psychrometrics::PsyCpAirFnW(air_hum_rat)); + this->SumSysMCp += MassFlowRate_CpAir; + this->SumSysMCpT += MassFlowRate_CpAir * node.Temp; } // add in the leaks for (int ADUListIndex = 1, ADUListIndex_end = zrpc.NumADUs; ADUListIndex <= ADUListIndex_end; ++ADUListIndex) { auto &airDistUnit = state.dataDefineEquipment->AirDistUnit(zrpc.ADUIndex(ADUListIndex)); if (airDistUnit.UpStreamLeak) { - Real64 const MassFlowRate_CpAir(airDistUnit.MassFlowRateUpStrLk * PsyCpAirFnW(air_hum_rat)); - SumSysMCp += MassFlowRate_CpAir; - SumSysMCpT += MassFlowRate_CpAir * state.dataLoopNodes->Node(airDistUnit.InletNodeNum).Temp; + Real64 const MassFlowRate_CpAir(airDistUnit.MassFlowRateUpStrLk * Psychrometrics::PsyCpAirFnW(air_hum_rat)); + this->SumSysMCp += MassFlowRate_CpAir; + this->SumSysMCpT += MassFlowRate_CpAir * state.dataLoopNodes->Node(airDistUnit.InletNodeNum).Temp; } if (airDistUnit.DownStreamLeak) { - Real64 const MassFlowRate_CpAir(airDistUnit.MassFlowRateDnStrLk * PsyCpAirFnW(air_hum_rat)); - SumSysMCp += MassFlowRate_CpAir; - SumSysMCpT += MassFlowRate_CpAir * state.dataLoopNodes->Node(airDistUnit.OutletNodeNum).Temp; + Real64 const MassFlowRate_CpAir(airDistUnit.MassFlowRateDnStrLk * Psychrometrics::PsyCpAirFnW(air_hum_rat)); + this->SumSysMCp += MassFlowRate_CpAir; + this->SumSysMCpT += MassFlowRate_CpAir * state.dataLoopNodes->Node(airDistUnit.OutletNodeNum).Temp; } } - } else if (ZoneSupPlenumAirFlag) { - Real64 MassFlowRate = state.dataLoopNodes->Node(state.dataZonePlenum->ZoneSupPlenCond(zone.PlenumCondNum).InletNode).MassFlowRate; - Real64 CpAir = PsyCpAirFnW(state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)); - SumSysMCp += MassFlowRate * CpAir; - SumSysMCpT += MassFlowRate * CpAir * state.dataLoopNodes->Node(state.dataZonePlenum->ZoneSupPlenCond(zone.PlenumCondNum).InletNode).Temp; + } else if (thisZone.IsSupplyPlenum) { + Real64 MassFlowRate = state.dataLoopNodes->Node(state.dataZonePlenum->ZoneSupPlenCond(thisZone.PlenumCondNum).InletNode).MassFlowRate; + Real64 CpAir = Psychrometrics::PsyCpAirFnW(this->ZoneAirHumRat); + this->SumSysMCp += MassFlowRate * CpAir; + this->SumSysMCpT += + MassFlowRate * CpAir * state.dataLoopNodes->Node(state.dataZonePlenum->ZoneSupPlenCond(thisZone.PlenumCondNum).InletNode).Temp; } - int ZoneMult = zone.Multiplier * zone.ListMultiplier; + int ZoneMult = thisZone.Multiplier * thisZone.ListMultiplier; - SumSysMCp /= ZoneMult; - SumSysMCpT /= ZoneMult; + this->SumSysMCp /= ZoneMult; + this->SumSysMCpT /= ZoneMult; } - // Sum all surface convection: SumHA, SumHATsurf, SumHATref (and additional contributions to SumIntGain) - for (int SurfNum = zone.HTSurfaceFirst; SurfNum <= zone.HTSurfaceLast; ++SurfNum) { + + if (spaceNum > 0) { + Real64 spaceFrac = state.dataHeatBal->space(spaceNum).fracZoneVolume; + this->SumSysMCp *= spaceFrac; + this->SumSysMCpT *= spaceFrac; + } + + // Sum all surface convection: this->SumHA, this->SumHATsurf, this->SumHATref (and additional contributions to this->SumIntGain) + SumHATOutput sumHATResults; // space or zone return values + sumHATResults = this->calcSumHAT(state, zoneNum, spaceNum); + this->SumIntGain += sumHATResults.sumIntGain; + this->SumHA = sumHATResults.sumHA; + this->SumHATsurf = sumHATResults.sumHATsurf; + this->SumHATref = sumHATResults.sumHATref; +} + +SumHATOutput ZoneHeatBalanceData::calcSumHAT(EnergyPlusData &state, int const zoneNum, [[maybe_unused]] int const spaceNum) +{ + assert(zoneNum > 0); + assert(spaceNum == 0); + SumHATOutput zoneResults; // zone-level return values + for (int zoneSpaceNum : state.dataHeatBal->Zone(zoneNum).spaceIndexes) { + SumHATOutput spaceResults; // temporary return value from space-level calcSumHAT + spaceResults = state.dataZoneTempPredictorCorrector->spaceHeatBalance(zoneSpaceNum).calcSumHAT(state, zoneNum, zoneSpaceNum); + zoneResults.sumIntGain += spaceResults.sumIntGain; + zoneResults.sumHA += spaceResults.sumHA; + zoneResults.sumHATsurf += spaceResults.sumHATsurf; + zoneResults.sumHATref += spaceResults.sumHATref; + } + return zoneResults; +} + +SumHATOutput SpaceHeatBalanceData::calcSumHAT(EnergyPlusData &state, int const zoneNum, int const spaceNum) +{ + assert(zoneNum > 0); + assert(spaceNum > 0); + auto &thisZone = state.dataHeatBal->Zone(zoneNum); + auto &thisSpace = state.dataHeatBal->space(spaceNum); + SumHATOutput results; // space-level return values + + for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) { Real64 HA = 0.0; Real64 Area = state.dataSurface->Surface(SurfNum).Area; // For windows, this is the glazing area if (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window) { - auto const shading_flag(state.dataSurface->SurfWinShadingFlag(SurfNum)); + DataSurfaces::WinShadingType const shading_flag = state.dataSurface->SurfWinShadingFlag(SurfNum); // Add to the convective internal gains if (ANY_INTERIOR_SHADE_BLIND(shading_flag)) { @@ -6303,21 +5607,21 @@ void CalcZoneSums(EnergyPlusData &state, // from the inside surface of the divider goes directly into the zone air -- i.e., the IR radiative // interaction between divider and shade or blind is ignored due to the difficulty of calculating this interaction // at the same time that the interaction between glass and shade is calculated. - SumIntGain += state.dataSurface->SurfWinDividerHeatGain(SurfNum); + results.sumIntGain += state.dataSurface->SurfWinDividerHeatGain(SurfNum); } // Other convection term is applicable to equivalent layer window (ASHWAT) model if (state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).WindowTypeEQL) - SumIntGain += state.dataSurface->SurfWinOtherConvHeatGain(SurfNum); + results.sumIntGain += state.dataSurface->SurfWinOtherConvHeatGain(SurfNum); // Convective heat gain from natural convection in gap between glass and interior shade or blind - if (ANY_INTERIOR_SHADE_BLIND(shading_flag)) SumIntGain += state.dataSurface->SurfWinConvHeatFlowNatural(SurfNum); + if (ANY_INTERIOR_SHADE_BLIND(shading_flag)) results.sumIntGain += state.dataSurface->SurfWinConvHeatFlowNatural(SurfNum); // Convective heat gain from airflow window if (state.dataSurface->SurfWinAirflowThisTS(SurfNum) > 0.0) { - SumIntGain += state.dataSurface->SurfWinConvHeatGainToZoneAir(SurfNum); - if (zone.NoHeatToReturnAir) { - SumIntGain += state.dataSurface->SurfWinRetHeatGainToZoneAir(SurfNum); + results.sumIntGain += state.dataSurface->SurfWinConvHeatGainToZoneAir(SurfNum); + if (thisZone.NoHeatToReturnAir) { + results.sumIntGain += state.dataSurface->SurfWinRetHeatGainToZoneAir(SurfNum); state.dataSurface->SurfWinHeatGain(SurfNum) += state.dataSurface->SurfWinRetHeatGainToZoneAir(SurfNum); if (state.dataSurface->SurfWinHeatGain(SurfNum) >= 0.0) { state.dataSurface->SurfWinHeatGainRep(SurfNum) = state.dataSurface->SurfWinHeatGain(SurfNum); @@ -6338,7 +5642,7 @@ void CalcZoneSums(EnergyPlusData &state, // Window frame contribution Real64 const HA_surf(state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinFrameArea(SurfNum) * (1.0 + state.dataSurface->SurfWinProjCorrFrIn(SurfNum))); - SumHATsurf += HA_surf * state.dataSurface->SurfWinFrameTempIn(SurfNum); + results.sumHATsurf += HA_surf * state.dataSurface->SurfWinFrameTempIn(SurfNum); HA += HA_surf; } @@ -6346,47 +5650,49 @@ void CalcZoneSums(EnergyPlusData &state, // Window divider contribution (only from shade or blind for window with divider and interior shade or blind) Real64 const HA_surf(state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinDividerArea(SurfNum) * (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivIn(SurfNum))); - SumHATsurf += HA_surf * state.dataSurface->SurfWinDividerTempIn(SurfNum); + results.sumHATsurf += HA_surf * state.dataSurface->SurfWinDividerTempIn(SurfNum); HA += HA_surf; } } // End of check if window HA += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * Area; - SumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * Area * state.dataHeatBalSurf->SurfTempInTmp(SurfNum); + results.sumHATsurf += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * Area * state.dataHeatBalSurf->SurfTempInTmp(SurfNum); // determine reference air temperature for this surface switch (state.dataSurface->SurfTAirRef(SurfNum)) { case DataSurfaces::RefAirTemp::ZoneMeanAirTemp: // The zone air is the reference temperature (which is to be solved for in CorrectZoneAirTemp). - SumHA += HA; + results.sumHA += HA; break; case DataSurfaces::RefAirTemp::AdjacentAirTemp: - SumHATref += HA * state.dataHeatBal->SurfTempEffBulkAir(SurfNum); + results.sumHATref += HA * state.dataHeatBal->SurfTempEffBulkAir(SurfNum); break; case DataSurfaces::RefAirTemp::ZoneSupplyAirTemp: // check whether this zone is a controlled zone or not - if (!ControlledZoneAirFlag) { - ShowFatalError(state, "Zones must be controlled for Ceiling-Diffuser Convection model. No system serves zone " + zone.Name); - return; + if (!thisZone.IsControlled) { + ShowFatalError(state, "Zones must be controlled for Ceiling-Diffuser Convection model. No system serves zone " + thisZone.Name); + return results; } // determine supply air temperature as a weighted average of the inlet temperatures. - if (SumSysMCp > 0.0) { - SumHATref += HA * SumSysMCpT / SumSysMCp; + // TODO: For now, use zone-level values for system flow + if (state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum).SumSysMCp > 0.0) { + results.sumHATref += HA * state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum).SumSysMCpT / + state.dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum).SumSysMCp; } else { // no system flow (yet) so just use zone air temperature #5906 - SumHA += HA; + results.sumHA += HA; } break; default: // currently set to mean air temp but should add error warning here - SumHA += HA; + results.sumHA += HA; break; } } // SurfNum + return results; } - void CalcZoneComponentLoadSums(EnergyPlusData &state, int const ZoneNum, // Zone number Real64 const TempDepCoef, // Dependent coefficient @@ -6434,35 +5740,28 @@ void CalcZoneComponentLoadSums(EnergyPlusData &state, imBalance = 0.0; SumEnthalpyM = 0.0; SumEnthalpyH = 0.0; - Real64 ADUHeatAddRate = 0.0; - Real64 QSensRate = 0.0; - auto &zone = state.dataHeatBal->Zone(ZoneNum); - auto &MAT = state.dataHeatBalFanSys->MAT(ZoneNum); - auto &Node = state.dataLoopNodes->Node; - auto &zoneAirHumRat = state.dataHeatBalFanSys->ZoneAirHumRat(ZoneNum); + auto &thisZone = state.dataHeatBal->Zone(ZoneNum); + auto const &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); // Sum all convective internal gains: SumIntGain - SumIntGains = InternalHeatGains::SumAllInternalConvectionGains(state, ZoneNum); + SumIntGains = InternalHeatGains::zoneSumAllInternalConvectionGains(state, ZoneNum); // Add heat to return air if zonal system (no return air) or cycling system (return air frequently very // low or zero) - if (zone.NoHeatToReturnAir) { - SumIntGains += InternalHeatGains::SumAllReturnAirConvectionGains(state, ZoneNum, 0); + if (thisZone.NoHeatToReturnAir) { + SumIntGains += InternalHeatGains::zoneSumAllReturnAirConvectionGains(state, ZoneNum, 0); } // sum non-system air flow transfers between zones - SumMCpDTzones = state.dataHeatBalFanSys->MCPTM(ZoneNum) - state.dataHeatBalFanSys->MCPM(ZoneNum) * MAT; // but maybe it should be ZTAV(ZoneNum) + SumMCpDTzones = thisZoneHB.MCPTM - thisZoneHB.MCPM * thisZoneHB.MAT; // but maybe it should be ZTAV(ZoneNum) // Sum non-system air flow, i.e. infiltration, simple ventilation, earth tube // reuse SumMCp, SumMCpT from CalcZoneSum but use MAT (or maybe ZTAV?) to complete - SumMCpDtInfil = - (state.dataHeatBalFanSys->MCPTI(ZoneNum) - state.dataHeatBalFanSys->MCPI(ZoneNum) * MAT) + - (state.dataHeatBalFanSys->MCPTV(ZoneNum) - state.dataHeatBalFanSys->MCPV(ZoneNum) * MAT) + - (state.dataHeatBalFanSys->MCPTE(ZoneNum) - state.dataHeatBalFanSys->MCPE(ZoneNum) * MAT) + - (state.dataHeatBalFanSys->MCPTC(ZoneNum) - state.dataHeatBalFanSys->MCPC(ZoneNum) * MAT) + - (state.dataHeatBalFanSys->MDotCPOA(ZoneNum) * zone.OutDryBulbTemp - - state.dataHeatBalFanSys->MDotCPOA(ZoneNum) * MAT); // infiltration | Ventilation (simple) | Earth tube. | Cooltower | combined OA flow + SumMCpDtInfil = (thisZoneHB.MCPTI - thisZoneHB.MCPI * thisZoneHB.MAT) + (thisZoneHB.MCPTV - thisZoneHB.MCPV * thisZoneHB.MAT) + + (thisZoneHB.MCPTE - thisZoneHB.MCPE * thisZoneHB.MAT) + (thisZoneHB.MCPTC - thisZoneHB.MCPC * thisZoneHB.MAT) + + (thisZoneHB.MDotCPOA * thisZone.OutDryBulbTemp - + thisZoneHB.MDotCPOA * thisZoneHB.MAT); // infiltration | Ventilation (simple) | Earth tube. | Cooltower | combined OA flow // Sum all multizone air flow calculated from AirflowNetwork by assuming no simple air infiltration model (if used) if (state.afn->multizone_always_simulated || @@ -6470,24 +5769,28 @@ void CalcZoneComponentLoadSums(EnergyPlusData &state, state.afn->AirflowNetworkFanActivated)) { // Multizone airflow calculated in AirflowNetwork SumMCpDtInfil = state.afn->exchangeData(ZoneNum).SumMCpT + state.afn->exchangeData(ZoneNum).SumMVCpT - - (state.afn->exchangeData(ZoneNum).SumMCp + state.afn->exchangeData(ZoneNum).SumMVCp) * state.dataHeatBalFanSys->MAT(ZoneNum); - SumMCpDTzones = state.afn->exchangeData(ZoneNum).SumMMCpT - state.afn->exchangeData(ZoneNum).SumMMCp * MAT; + (state.afn->exchangeData(ZoneNum).SumMCp + state.afn->exchangeData(ZoneNum).SumMVCp) * thisZoneHB.MAT; + SumMCpDTzones = state.afn->exchangeData(ZoneNum).SumMMCpT - state.afn->exchangeData(ZoneNum).SumMMCp * thisZoneHB.MAT; } // Sum all system air flow: reusing how SumSysMCp, SumSysMCpT are calculated in CalcZoneSums // Plenum and controlled zones have a different set of inlet nodes which must be calculated. - if (zone.IsControlled) { + Real64 QSensRate = 0.0; + if (thisZone.IsControlled) { auto &zoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(ZoneNum); for (int NodeNum = 1; NodeNum <= zoneEquipConfig.NumInletNodes; ++NodeNum) { // Get node conditions - CalcZoneSensibleOutput( - Node(zoneEquipConfig.InletNode(NodeNum)).MassFlowRate, Node(zoneEquipConfig.InletNode(NodeNum)).Temp, MAT, zoneAirHumRat, QSensRate); + Real64 const NodeTemp = state.dataLoopNodes->Node(zoneEquipConfig.InletNode(NodeNum)).Temp; + Real64 const MassFlowRate = state.dataLoopNodes->Node(zoneEquipConfig.InletNode(NodeNum)).MassFlowRate; + QSensRate = calcZoneSensibleOutput(MassFlowRate, NodeTemp, thisZoneHB.MAT, thisZoneHB.ZoneAirHumRat); SumMCpDTsystem += QSensRate; if (zoneEquipConfig.InletNodeADUNum(NodeNum) > 0) { auto &airDistUnit = state.dataDefineEquipment->AirDistUnit(zoneEquipConfig.InletNodeADUNum(NodeNum)); - CalcZoneSensibleOutput( - Node(airDistUnit.OutletNodeNum).MassFlowRate, Node(airDistUnit.OutletNodeNum).Temp, MAT, zoneAirHumRat, ADUHeatAddRate); + Real64 ADUHeatAddRate = calcZoneSensibleOutput(state.dataLoopNodes->Node(airDistUnit.OutletNodeNum).MassFlowRate, + state.dataLoopNodes->Node(airDistUnit.OutletNodeNum).Temp, + thisZoneHB.MAT, + thisZoneHB.ZoneAirHumRat); airDistUnit.HeatRate = max(0.0, ADUHeatAddRate); airDistUnit.CoolRate = std::abs(min(0.0, ADUHeatAddRate)); airDistUnit.HeatGain = airDistUnit.HeatRate * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour; @@ -6495,113 +5798,127 @@ void CalcZoneComponentLoadSums(EnergyPlusData &state, } } - } else if (zone.IsReturnPlenum) { - auto &zoneRetPlenCond = state.dataZonePlenum->ZoneRetPlenCond(zone.PlenumCondNum); + } else if (thisZone.IsReturnPlenum) { + auto &zoneRetPlenCond = state.dataZonePlenum->ZoneRetPlenCond(thisZone.PlenumCondNum); for (int NodeNum = 1; NodeNum <= zoneRetPlenCond.NumInletNodes; ++NodeNum) { - CalcZoneSensibleOutput( - Node(zoneRetPlenCond.InletNode(NodeNum)).MassFlowRate, Node(zoneRetPlenCond.InletNode(NodeNum)).Temp, MAT, zoneAirHumRat, QSensRate); + QSensRate = calcZoneSensibleOutput(state.dataLoopNodes->Node(zoneRetPlenCond.InletNode(NodeNum)).MassFlowRate, + state.dataLoopNodes->Node(zoneRetPlenCond.InletNode(NodeNum)).Temp, + thisZoneHB.MAT, + thisZoneHB.ZoneAirHumRat); SumMCpDTsystem += QSensRate; } // add in the leaks for (int ADUListIndex = 1; ADUListIndex <= zoneRetPlenCond.NumADUs; ++ADUListIndex) { auto &airDistUnit = state.dataDefineEquipment->AirDistUnit(zoneRetPlenCond.ADUIndex(ADUListIndex)); if (airDistUnit.UpStreamLeak) { - CalcZoneSensibleOutput(airDistUnit.MassFlowRateUpStrLk, Node(airDistUnit.InletNodeNum).Temp, MAT, zoneAirHumRat, QSensRate); + QSensRate = calcZoneSensibleOutput(airDistUnit.MassFlowRateUpStrLk, + state.dataLoopNodes->Node(airDistUnit.InletNodeNum).Temp, + thisZoneHB.MAT, + thisZoneHB.ZoneAirHumRat); SumMCpDTsystem += QSensRate; } if (airDistUnit.DownStreamLeak) { - CalcZoneSensibleOutput(airDistUnit.MassFlowRateDnStrLk, Node(airDistUnit.OutletNodeNum).Temp, MAT, zoneAirHumRat, QSensRate); + QSensRate = calcZoneSensibleOutput(airDistUnit.MassFlowRateDnStrLk, + state.dataLoopNodes->Node(airDistUnit.OutletNodeNum).Temp, + thisZoneHB.MAT, + thisZoneHB.ZoneAirHumRat); SumMCpDTsystem += QSensRate; } } - } else if (zone.IsSupplyPlenum) { - auto &zoneSupPlenCond = state.dataZonePlenum->ZoneSupPlenCond(zone.PlenumCondNum); - CalcZoneSensibleOutput(Node(zoneSupPlenCond.InletNode).MassFlowRate, Node(zoneSupPlenCond.InletNode).Temp, MAT, zoneAirHumRat, QSensRate); + } else if (thisZone.IsSupplyPlenum) { + auto &zoneSupPlenCond = state.dataZonePlenum->ZoneSupPlenCond(thisZone.PlenumCondNum); + QSensRate = calcZoneSensibleOutput(state.dataLoopNodes->Node(zoneSupPlenCond.InletNode).MassFlowRate, + state.dataLoopNodes->Node(zoneSupPlenCond.InletNode).Temp, + thisZoneHB.MAT, + thisZoneHB.ZoneAirHumRat); SumMCpDTsystem += QSensRate; } // non air system response. - SumNonAirSystem = state.dataHeatBalFanSys->NonAirSystemResponse(ZoneNum) + state.dataHeatBalFanSys->SumConvHTRadSys(ZoneNum) + - state.dataHeatBalFanSys->SumConvPool(ZoneNum); + SumNonAirSystem = + thisZoneHB.NonAirSystemResponse + state.dataHeatBalFanSys->SumConvHTRadSys(ZoneNum) + state.dataHeatBalFanSys->SumConvPool(ZoneNum); // Sum all surface convection: SumHA, SumHATsurf, SumHATref (and additional contributions to SumIntGain) - for (int SurfNum = zone.HTSurfaceFirst; SurfNum <= zone.HTSurfaceLast; ++SurfNum) { - - Real64 Area = state.dataSurface->Surface(SurfNum).Area; // For windows, this is the glazing area - Real64 RefAirTemp = state.dataSurface->Surface(SurfNum).getInsideAirTemperature(state, SurfNum); - - if (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window) { - - // Add to the convective internal gains - if (ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum))) { - // The shade area covers the area of the glazing plus the area of the dividers. - Area += state.dataSurface->SurfWinDividerArea(SurfNum); - // If interior shade or blind is present it is assumed that both the convective and IR radiative gain - // from the inside surface of the divider goes directly into the zone air -- i.e., the IR radiative - // interaction between divider and shade or blind is ignored due to the difficulty of calculating this interaction - // at the same time that the interaction between glass and shade is calculated. - SumIntGains += state.dataSurface->SurfWinDividerHeatGain(SurfNum); - } + for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) { + auto &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 + Real64 RefAirTemp = state.dataSurface->Surface(SurfNum).getInsideAirTemperature(state, SurfNum); + + if (state.dataSurface->Surface(SurfNum).Class == DataSurfaces::SurfaceClass::Window) { + + // Add to the convective internal gains + if (ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum))) { + // The shade area covers the area of the glazing plus the area of the dividers. + Area += state.dataSurface->SurfWinDividerArea(SurfNum); + // If interior shade or blind is present it is assumed that both the convective and IR radiative gain + // from the inside surface of the divider goes directly into the zone air -- i.e., the IR radiative + // interaction between divider and shade or blind is ignored due to the difficulty of calculating this interaction + // at the same time that the interaction between glass and shade is calculated. + SumIntGains += state.dataSurface->SurfWinDividerHeatGain(SurfNum); + } - // Other convection term is applicable to equivalent layer window (ASHWAT) model - if (state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).WindowTypeEQL) - SumIntGains += state.dataSurface->SurfWinOtherConvHeatGain(SurfNum); + // Other convection term is applicable to equivalent layer window (ASHWAT) model + if (state.dataConstruction->Construct(state.dataSurface->Surface(SurfNum).Construction).WindowTypeEQL) + SumIntGains += state.dataSurface->SurfWinOtherConvHeatGain(SurfNum); - // Convective heat gain from natural convection in gap between glass and interior shade or blind - if (ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum))) - SumIntGains += state.dataSurface->SurfWinConvHeatFlowNatural(SurfNum); + // Convective heat gain from natural convection in gap between glass and interior shade or blind + if (ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum))) + SumIntGains += state.dataSurface->SurfWinConvHeatFlowNatural(SurfNum); - // Convective heat gain from airflow window - if (state.dataSurface->SurfWinAirflowThisTS(SurfNum) > 0.0) { - SumIntGains += state.dataSurface->SurfWinConvHeatGainToZoneAir(SurfNum); - if (zone.NoHeatToReturnAir) { - SumIntGains += state.dataSurface->SurfWinRetHeatGainToZoneAir(SurfNum); + // Convective heat gain from airflow window + if (state.dataSurface->SurfWinAirflowThisTS(SurfNum) > 0.0) { + SumIntGains += state.dataSurface->SurfWinConvHeatGainToZoneAir(SurfNum); + if (thisZone.NoHeatToReturnAir) { + SumIntGains += state.dataSurface->SurfWinRetHeatGainToZoneAir(SurfNum); + } } - } - // Add to the surface convection sums - if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) { - // Window frame contribution - SumHADTsurfs += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinFrameArea(SurfNum) * - (1.0 + state.dataSurface->SurfWinProjCorrFrIn(SurfNum)) * - (state.dataSurface->SurfWinFrameTempIn(SurfNum) - RefAirTemp); - } + // Add to the surface convection sums + if (state.dataSurface->SurfWinFrameArea(SurfNum) > 0.0) { + // Window frame contribution + SumHADTsurfs += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinFrameArea(SurfNum) * + (1.0 + state.dataSurface->SurfWinProjCorrFrIn(SurfNum)) * + (state.dataSurface->SurfWinFrameTempIn(SurfNum) - RefAirTemp); + } - if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0 && !ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum))) { - // Window divider contribution (only from shade or blind for window with divider and interior shade or blind) - SumHADTsurfs += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinDividerArea(SurfNum) * - (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) * - (state.dataSurface->SurfWinDividerTempIn(SurfNum) - RefAirTemp); - } + if (state.dataSurface->SurfWinDividerArea(SurfNum) > 0.0 && + !ANY_INTERIOR_SHADE_BLIND(state.dataSurface->SurfWinShadingFlag(SurfNum))) { + // Window divider contribution (only from shade or blind for window with divider and interior shade or blind) + SumHADTsurfs += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * state.dataSurface->SurfWinDividerArea(SurfNum) * + (1.0 + 2.0 * state.dataSurface->SurfWinProjCorrDivIn(SurfNum)) * + (state.dataSurface->SurfWinDividerTempIn(SurfNum) - RefAirTemp); + } - } // End of check if window + } // End of check if window - SumHADTsurfs += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * Area * (state.dataHeatBalSurf->SurfTempInTmp(SurfNum) - RefAirTemp); + SumHADTsurfs += state.dataHeatBalSurf->SurfHConvInt(SurfNum) * Area * (state.dataHeatBalSurf->SurfTempInTmp(SurfNum) - RefAirTemp); - // Accumulate Zone Phase Change Material Melting/Freezing Enthalpy output variables - if (state.dataSurface->Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) { - state.dataHeatBal->ZnAirRpt(ZoneNum).SumEnthalpyM += state.dataHeatBalFiniteDiffMgr->SurfaceFD(SurfNum).EnthalpyM; - state.dataHeatBal->ZnAirRpt(ZoneNum).SumEnthalpyH += state.dataHeatBalFiniteDiffMgr->SurfaceFD(SurfNum).EnthalpyF; + // Accumulate Zone Phase Change Material Melting/Freezing Enthalpy output variables + if (state.dataSurface->Surface(SurfNum).HeatTransferAlgorithm == DataSurfaces::HeatTransferModel::CondFD) { + state.dataHeatBal->ZnAirRpt(ZoneNum).SumEnthalpyM += state.dataHeatBalFiniteDiffMgr->SurfaceFD(SurfNum).EnthalpyM; + state.dataHeatBal->ZnAirRpt(ZoneNum).SumEnthalpyH += state.dataHeatBalFiniteDiffMgr->SurfaceFD(SurfNum).EnthalpyF; + } } } - // now calculate air energy storage source term. // capacitance is volume * density * heat capacity - Real64 CpAir = PsyCpAirFnW(zoneAirHumRat); - Real64 RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, MAT, zoneAirHumRat); + Real64 CpAir = Psychrometrics::PsyCpAirFnW(thisZoneHB.ZoneAirHumRat); + Real64 RhoAir = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, thisZoneHB.MAT, thisZoneHB.ZoneAirHumRat); switch (state.dataHeatBal->ZoneAirSolutionAlgo) { case DataHeatBalance::SolutionAlgo::ThirdOrder: { - CzdTdt = RhoAir * CpAir * zone.Volume * zone.ZoneVolCapMultpSens * (MAT - state.dataHeatBalFanSys->ZTM1(ZoneNum)) / + CzdTdt = RhoAir * CpAir * thisZone.Volume * thisZone.ZoneVolCapMultpSens * (thisZoneHB.MAT - thisZoneHB.ZTM[0]) / (state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour); // Exact solution } break; case DataHeatBalance::SolutionAlgo::AnalyticalSolution: { - CzdTdt = TempIndCoef - TempDepCoef * MAT; + CzdTdt = TempIndCoef - TempDepCoef * thisZoneHB.MAT; } break; case DataHeatBalance::SolutionAlgo::EulerMethod: { - CzdTdt = state.dataHeatBalFanSys->AIRRAT(ZoneNum) * (MAT - state.dataHeatBalFanSys->ZoneT1(ZoneNum)); + CzdTdt = thisZoneHB.AirPowerCap * (thisZoneHB.MAT - thisZoneHB.ZoneT1); } break; default: break; @@ -6616,8 +5933,8 @@ void CalcZoneComponentLoadSums(EnergyPlusData &state, pow_2(SumMCpDTsystem) + pow_2(SumNonAirSystem) + pow_2(CzdTdt)); if ((std::abs(imBalance) > Threshold) && (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing)) { // air balance is out by more than threshold - if (zone.AirHBimBalanceErrIndex == 0) { - ShowWarningMessage(state, format("Zone Air Heat Balance is out of balance for zone named {}", zone.Name)); + if (thisZone.AirHBimBalanceErrIndex == 0) { + ShowWarningMessage(state, format("Zone Air Heat Balance is out of balance for zone named {}", thisZone.Name)); ShowContinueError(state, format("Zone Air Heat Balance Deviation Rate is more than {:.1R} {{W}}", Threshold)); if (state.dataHVACGlobal->TurnFansOn) { ShowContinueError(state, "Night cycle fan operation may be causing above error"); @@ -6626,8 +5943,8 @@ void CalcZoneComponentLoadSums(EnergyPlusData &state, ShowContinueErrorTimeStamp(state, " Occurrence info:"); } ShowRecurringWarningErrorAtEnd(state, - format("Zone Air Heat Balance is out of balance ... zone named {}", zone.Name), - zone.AirHBimBalanceErrIndex, + format("Zone Air Heat Balance is out of balance ... zone named {}", thisZone.Name), + thisZone.AirHBimBalanceErrIndex, std::abs(imBalance) - Threshold, std::abs(imBalance) - Threshold, _, @@ -6652,7 +5969,7 @@ bool VerifyThermostatInZone(EnergyPlusData &state, std::string const &ZoneName) state.dataZoneCtrls->GetZoneAirStatsInputFlag = false; } if (state.dataZoneCtrls->NumTempControlledZones > 0) { - if (UtilityRoutines::FindItemInList(ZoneName, state.dataZoneCtrls->TempControlledZone, &ZoneTempControls::ZoneName) > 0) { + if (UtilityRoutines::FindItemInList(ZoneName, state.dataZoneCtrls->TempControlledZone, &DataZoneControls::ZoneTempControls::ZoneName) > 0) { return true; } else { return false; @@ -6759,7 +6076,7 @@ void DetectOscillatingZoneTemp(EnergyPlusData &state) auto &TimeStepSys = state.dataHVACGlobal->TimeStepSys; if (state.dataZoneTempPredictorCorrector->OscillationVariablesNeeded) { // precalc the negative value for performance - Real64 NegOscillateMagnitude = -OscillateMagnitude; + Real64 NegOscillateMagnitude = -DataHVACGlobals::OscillateMagnitude; // assume no zone is oscillating bool isAnyZoneOscillating = false; bool isAnyZoneOscillatingDuringOccupancy = false; @@ -6770,7 +6087,7 @@ void DetectOscillatingZoneTemp(EnergyPlusData &state) state.dataZoneTempPredictorCorrector->ZoneTempHist(4, iZone) = state.dataZoneTempPredictorCorrector->ZoneTempHist(3, iZone); state.dataZoneTempPredictorCorrector->ZoneTempHist(3, iZone) = state.dataZoneTempPredictorCorrector->ZoneTempHist(2, iZone); state.dataZoneTempPredictorCorrector->ZoneTempHist(2, iZone) = state.dataZoneTempPredictorCorrector->ZoneTempHist(1, iZone); - state.dataZoneTempPredictorCorrector->ZoneTempHist(1, iZone) = state.dataHeatBalFanSys->ZT(iZone); + state.dataZoneTempPredictorCorrector->ZoneTempHist(1, iZone) = state.dataZoneTempPredictorCorrector->zoneHeatBalance(iZone).ZT; Real64 Diff34 = state.dataZoneTempPredictorCorrector->ZoneTempHist(3, iZone) - state.dataZoneTempPredictorCorrector->ZoneTempHist(4, iZone); Real64 Diff23 = @@ -6778,16 +6095,16 @@ void DetectOscillatingZoneTemp(EnergyPlusData &state) Real64 Diff12 = state.dataZoneTempPredictorCorrector->ZoneTempHist(1, iZone) - state.dataZoneTempPredictorCorrector->ZoneTempHist(2, iZone); // roll out the conditionals for increased performance - if (Diff12 > OscillateMagnitude) { + if (Diff12 > DataHVACGlobals::OscillateMagnitude) { if (Diff23 < NegOscillateMagnitude) { - if (Diff34 > OscillateMagnitude) { + if (Diff34 > DataHVACGlobals::OscillateMagnitude) { isOscillate = true; } } } // now try the opposite sequence of swings if (Diff12 < NegOscillateMagnitude) { - if (Diff23 > OscillateMagnitude) { + if (Diff23 > DataHVACGlobals::OscillateMagnitude) { if (Diff34 < NegOscillateMagnitude) { isOscillate = true; } @@ -6845,8 +6162,9 @@ void AdjustAirSetPointsforOpTempCntrl(EnergyPlusData &state, int const TempContr if (!(tempControlledZone.OperativeTempControl)) return; // do nothing to setpoint // is operative temp radiative fraction scheduled or fixed? - thisMRTFraction = (tempControlledZone.OpTempCntrlModeScheduled) ? GetCurrentScheduleValue(state, tempControlledZone.OpTempRadiativeFractionSched) - : tempControlledZone.FixedRadiativeFraction; + thisMRTFraction = (tempControlledZone.OpTempCntrlModeScheduled) + ? ScheduleManager::GetCurrentScheduleValue(state, tempControlledZone.OpTempRadiativeFractionSched) + : tempControlledZone.FixedRadiativeFraction; // get mean radiant temperature for zone Real64 thisMRT = state.dataHeatBal->ZoneMRT(ActualZoneNum); @@ -7380,7 +6698,7 @@ void AdjustCoolingSetPointforTempAndHumidityControl(EnergyPlusData &state, ZoneOvercoolRange = min(ZoneOvercoolRange, MaxAllowedOvercoolRange); } // Calculate difference between zone air relative humidity and the dehumidifying setpoint - Real64 RelativeHumidityDiff = state.dataZoneTempPredictorCorrector->ZoneAirRelHum(ActualZoneNum) - + Real64 RelativeHumidityDiff = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ActualZoneNum).ZoneAirRelHum - ScheduleManager::GetCurrentScheduleValue(state, tempControlledZone.DehumidifyingSchedIndex); if (RelativeHumidityDiff > 0.0 && ZoneOvercoolControlRatio > 0.0) { // proportionally reset the cooling setpoint temperature downward (zone Overcool) @@ -7689,4 +7007,494 @@ temperatureAndCountInSch(EnergyPlusData &state, int const scheduleIndex, bool co return std::make_tuple(valueAtSelectTime, countOfSame, monthName); } +void ZoneSpaceHeatBalanceData::updateTemperatures(EnergyPlusData &state, + bool const ShortenTimeStepSys, + bool const UseZoneTimeStepHistory, + Real64 const PriorTimeStep, + int const zoneNum, + int const spaceNum) +{ + assert(zoneNum > 0); + if (ShortenTimeStepSys) { + // timestep has just shifted from full zone timestep to a new shorter system timestep + // throw away last updates in corrector and rewind for resimulating smaller timestep + if (spaceNum == 0) { + if (state.dataHeatBal->Zone(zoneNum).SystemZoneNodeNumber > 0) { // roll back result for zone air node, + auto &zoneNode = state.dataLoopNodes->Node(state.dataHeatBal->Zone(zoneNum).SystemZoneNodeNumber); + zoneNode.Temp = this->XMAT[0]; + state.dataHeatBalFanSys->TempTstatAir(zoneNum) = this->XMAT[0]; + zoneNode.HumRat = this->WPrevZoneTS[0]; + zoneNode.Enthalpy = Psychrometrics::PsyHFnTdbW(this->XMAT[0], this->WPrevZoneTS[0]); + } + } else { + if (state.dataHeatBal->space(spaceNum).SystemZoneNodeNumber > 0) { // roll back result for space air node, + auto &spaceNode = state.dataLoopNodes->Node(state.dataHeatBal->space(spaceNum).SystemZoneNodeNumber); + spaceNode.Temp = this->XMAT[0]; + state.dataHeatBalFanSys->TempTstatAir(zoneNum) = this->XMAT[0]; + spaceNode.HumRat = this->WPrevZoneTS[0]; + spaceNode.Enthalpy = Psychrometrics::PsyHFnTdbW(this->XMAT[0], this->WPrevZoneTS[0]); + } + } + + if (state.dataHVACGlobal->NumOfSysTimeSteps != + state.dataHVACGlobal->NumOfSysTimeStepsLastZoneTimeStep) { // cannot reuse existing DS data, interpolate from zone time + + this->MAT = DownInterpolate4HistoryValues(PriorTimeStep, state.dataHVACGlobal->TimeStepSys, this->XMAT, this->DSXMAT); + this->ZoneAirHumRat = + DownInterpolate4HistoryValues(PriorTimeStep, state.dataHVACGlobal->TimeStepSys, this->WPrevZoneTS, this->DSWPrevZoneTS); + + if (spaceNum == 0 && state.dataRoomAirMod->anyNonMixingRoomAirModel) { + if (state.dataRoomAirMod->IsZoneDV(zoneNum) || state.dataRoomAirMod->IsZoneUI(zoneNum)) { + + DownInterpolate4HistoryValues(PriorTimeStep, + state.dataHVACGlobal->TimeStepSys, + state.dataRoomAirMod->XMATFloor(zoneNum), + state.dataRoomAirMod->XM2TFloor(zoneNum), + state.dataRoomAirMod->XM3TFloor(zoneNum), + state.dataRoomAirMod->MATFloor(zoneNum), + state.dataRoomAirMod->DSXMATFloor(zoneNum), + state.dataRoomAirMod->DSXM2TFloor(zoneNum), + state.dataRoomAirMod->DSXM3TFloor(zoneNum), + state.dataRoomAirMod->DSXM4TFloor(zoneNum)); + DownInterpolate4HistoryValues(PriorTimeStep, + state.dataHVACGlobal->TimeStepSys, + state.dataRoomAirMod->XMATOC(zoneNum), + state.dataRoomAirMod->XM2TOC(zoneNum), + state.dataRoomAirMod->XM3TOC(zoneNum), + state.dataRoomAirMod->MATOC(zoneNum), + state.dataRoomAirMod->DSXMATOC(zoneNum), + state.dataRoomAirMod->DSXM2TOC(zoneNum), + state.dataRoomAirMod->DSXM3TOC(zoneNum), + state.dataRoomAirMod->DSXM4TOC(zoneNum)); + DownInterpolate4HistoryValues(PriorTimeStep, + state.dataHVACGlobal->TimeStepSys, + state.dataRoomAirMod->XMATMX(zoneNum), + state.dataRoomAirMod->XM2TMX(zoneNum), + state.dataRoomAirMod->XM3TMX(zoneNum), + state.dataRoomAirMod->MATMX(zoneNum), + state.dataRoomAirMod->DSXMATMX(zoneNum), + state.dataRoomAirMod->DSXM2TMX(zoneNum), + state.dataRoomAirMod->DSXM3TMX(zoneNum), + state.dataRoomAirMod->DSXM4TMX(zoneNum)); + } + if (state.dataRoomAirMod->AirModel(zoneNum).AirModelType == DataRoomAirModel::RoomAirModel::AirflowNetwork) { + for (int LoopNode = 1; LoopNode <= state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(zoneNum).NumOfAirNodes; ++LoopNode) { + auto &ThisRAFNNode(state.dataRoomAirMod->RoomAirflowNetworkZoneInfo(zoneNum).Node(LoopNode)); + DownInterpolate4HistoryValues(PriorTimeStep, + state.dataHVACGlobal->TimeStepSys, + ThisRAFNNode.AirTempX1, + ThisRAFNNode.AirTempX2, + ThisRAFNNode.AirTempX3, + ThisRAFNNode.AirTemp, + ThisRAFNNode.AirTempDSX1, + ThisRAFNNode.AirTempDSX2, + ThisRAFNNode.AirTempDSX3, + ThisRAFNNode.AirTempDSX4); + DownInterpolate4HistoryValues(PriorTimeStep, + state.dataHVACGlobal->TimeStepSys, + ThisRAFNNode.HumRatX1, + ThisRAFNNode.HumRatX2, + ThisRAFNNode.HumRatX3, + ThisRAFNNode.HumRat, + ThisRAFNNode.HumRatDSX1, + ThisRAFNNode.HumRatDSX2, + ThisRAFNNode.HumRatDSX3, + ThisRAFNNode.HumRatDSX4); + } + } + } + } else { // reuse history data in DS terms from last zone time step to preserve information that would be lost + // do nothing because DS history would have been pushed prior and should be ready + } + } + // now update the variables actually used in the balance equations. + if (UseZoneTimeStepHistory) { + this->ZTM = this->XMAT; + this->WPrevZoneTSTemp = this->WPrevZoneTS; + } else { // use down-stepped history + this->ZTM = this->DSXMAT; + this->WPrevZoneTSTemp = this->DSWPrevZoneTS; + } +} + +void ZoneSpaceHeatBalanceData::calcPredictedSystemLoad(EnergyPlusData &state, Real64 const RAFNFrac, int const zoneNum, int const spaceNum) +{ + // Calculate the predicted system load for a time step. + + assert(zoneNum > 0); + auto const &thisZone = state.dataHeatBal->Zone(zoneNum); + Real64 const thisTempZoneThermostatSetPoint = state.dataHeatBalFanSys->TempZoneThermostatSetPoint(zoneNum); + Real64 const thisZoneThermostatSetPointLo = state.dataHeatBalFanSys->ZoneThermostatSetPointLo(zoneNum); + Real64 const thisZoneThermostatSetPointHi = state.dataHeatBalFanSys->ZoneThermostatSetPointHi(zoneNum); + + bool thisDeadBandOrSetBack = false; + Real64 ZoneSetPoint = 0.0; + Real64 totalLoad = 0.0; + Real64 LoadToHeatingSetPoint = 0.0; + Real64 LoadToCoolingSetPoint = 0.0; + + switch (state.dataHeatBalFanSys->TempControlType(zoneNum)) { + case DataHVACGlobals::ThermostatType::Uncontrolled: + // Uncontrolled Zone + LoadToHeatingSetPoint = 0.0; + LoadToCoolingSetPoint = 0.0; + totalLoad = 0.0; + break; + case DataHVACGlobals::ThermostatType::SingleHeating: + switch (state.dataHeatBal->ZoneAirSolutionAlgo) { + case DataHeatBalance::SolutionAlgo::ThirdOrder: { + LoadToHeatingSetPoint = (this->TempDepZnLd * thisTempZoneThermostatSetPoint - this->TempIndZnLd); + break; + } + case DataHeatBalance::SolutionAlgo::AnalyticalSolution: { + if (this->TempDepZnLd == 0.0) { // B=0 + LoadToHeatingSetPoint = this->AirPowerCap * (thisTempZoneThermostatSetPoint - this->ZoneT1) - this->TempIndZnLd; + } else { + Real64 const exp_700_TA(std::exp(min(700.0, -this->TempDepZnLd / this->AirPowerCap))); + LoadToHeatingSetPoint = + this->TempDepZnLd * (thisTempZoneThermostatSetPoint - this->ZoneT1 * exp_700_TA) / (1.0 - exp_700_TA) - this->TempIndZnLd; + } + break; + } + case DataHeatBalance::SolutionAlgo::EulerMethod: { + LoadToHeatingSetPoint = this->AirPowerCap * (thisTempZoneThermostatSetPoint - this->ZoneT1) + + this->TempDepZnLd * (thisTempZoneThermostatSetPoint) - this->TempIndZnLd; + break; + } + default: { + assert(false); + } + } + if (RAFNFrac > 0.0) LoadToHeatingSetPoint = LoadToHeatingSetPoint / RAFNFrac; + totalLoad = LoadToHeatingSetPoint; + ZoneSetPoint = thisTempZoneThermostatSetPoint; + LoadToCoolingSetPoint = LoadToHeatingSetPoint; + // for consistency with the other cases, use LE instead of LT and don't subtract 1.0 Watt as a way of pushing the zero load + // case over the threshold + if ((totalLoad) <= 0.0) thisDeadBandOrSetBack = true; + + break; + case DataHVACGlobals::ThermostatType::SingleCooling: + switch (state.dataHeatBal->ZoneAirSolutionAlgo) { + case DataHeatBalance::SolutionAlgo::ThirdOrder: { + LoadToCoolingSetPoint = this->TempDepZnLd * thisTempZoneThermostatSetPoint - this->TempIndZnLd; + break; + } + case DataHeatBalance::SolutionAlgo::AnalyticalSolution: { + if (this->TempDepZnLd == 0.0) { // B=0 + LoadToCoolingSetPoint = this->AirPowerCap * (thisTempZoneThermostatSetPoint - this->ZoneT1) - this->TempIndZnLd; + } else { + Real64 const exp_700_TA(std::exp(min(700.0, -this->TempDepZnLd / this->AirPowerCap))); + LoadToCoolingSetPoint = + this->TempDepZnLd * (thisTempZoneThermostatSetPoint - this->ZoneT1 * exp_700_TA) / (1.0 - exp_700_TA) - this->TempIndZnLd; + } + break; + } + case DataHeatBalance::SolutionAlgo::EulerMethod: { + LoadToCoolingSetPoint = this->AirPowerCap * (thisTempZoneThermostatSetPoint - this->ZoneT1) + + this->TempDepZnLd * thisTempZoneThermostatSetPoint - this->TempIndZnLd; + break; + } + default: { + assert(false); + } + } + if (RAFNFrac > 0.0) LoadToHeatingSetPoint = LoadToHeatingSetPoint / RAFNFrac; + if (thisZone.HasAdjustedReturnTempByITE && !(state.dataGlobal->BeginSimFlag)) { + LoadToCoolingSetPoint = this->TempDepZnLd * thisZone.AdjustedReturnTempByITE - this->TempIndZnLd; + } + totalLoad = LoadToCoolingSetPoint; + ZoneSetPoint = thisTempZoneThermostatSetPoint; + LoadToHeatingSetPoint = LoadToCoolingSetPoint; + // for consistency with the other cases, use GE instead of GT and don't add 1.0 Watt as a way of pushing the zero load + // case over the threshold + if ((totalLoad) >= 0.0) thisDeadBandOrSetBack = true; + break; + case DataHVACGlobals::ThermostatType::SingleHeatCool: + switch (state.dataHeatBal->ZoneAirSolutionAlgo) { + case DataHeatBalance::SolutionAlgo::ThirdOrder: { + LoadToHeatingSetPoint = (this->TempDepZnLd * (thisTempZoneThermostatSetPoint) - this->TempIndZnLd); + LoadToCoolingSetPoint = (this->TempDepZnLd * (thisTempZoneThermostatSetPoint) - this->TempIndZnLd); + break; + } + case DataHeatBalance::SolutionAlgo::AnalyticalSolution: { + if (this->TempDepZnLd == 0.0) { // B=0 + LoadToHeatingSetPoint = this->AirPowerCap * (thisTempZoneThermostatSetPoint - this->ZoneT1) - this->TempIndZnLd; + LoadToCoolingSetPoint = this->AirPowerCap * (thisTempZoneThermostatSetPoint - this->ZoneT1) - this->TempIndZnLd; + } else { + Real64 const exp_700_TA(std::exp(min(700.0, -this->TempDepZnLd / this->AirPowerCap))); + LoadToHeatingSetPoint = + this->TempDepZnLd * (thisTempZoneThermostatSetPoint - this->ZoneT1 * exp_700_TA) / (1.0 - exp_700_TA) - this->TempIndZnLd; + LoadToCoolingSetPoint = + this->TempDepZnLd * (thisTempZoneThermostatSetPoint - this->ZoneT1 * exp_700_TA) / (1.0 - exp_700_TA) - this->TempIndZnLd; + } + break; + } + case DataHeatBalance::SolutionAlgo::EulerMethod: { + LoadToHeatingSetPoint = this->AirPowerCap * (thisTempZoneThermostatSetPoint - this->ZoneT1) + + this->TempDepZnLd * thisTempZoneThermostatSetPoint - this->TempIndZnLd; + LoadToCoolingSetPoint = this->AirPowerCap * (thisTempZoneThermostatSetPoint - this->ZoneT1) + + this->TempDepZnLd * thisTempZoneThermostatSetPoint - this->TempIndZnLd; + break; + } + default: { + assert(false); + } + } + ZoneSetPoint = thisTempZoneThermostatSetPoint; + if (RAFNFrac > 0.0) LoadToHeatingSetPoint = LoadToHeatingSetPoint / RAFNFrac; + if (RAFNFrac > 0.0) LoadToCoolingSetPoint = LoadToCoolingSetPoint / RAFNFrac; + + if (thisZone.HasAdjustedReturnTempByITE && !(state.dataGlobal->BeginSimFlag)) { + LoadToCoolingSetPoint = this->TempDepZnLd * thisZone.AdjustedReturnTempByITE - this->TempIndZnLd; + } + + // Note that LoadToHeatingSetPoint is generally not equal to LoadToCoolingSetPoint + // when the heating and cooling set-points are equal if the zone is unmixed, + // e.g. displacement ventilation or UFAD, since the stratification is generally not the same in heating and cooling modes + + // Possible combinations: + // 1/ LoadToHeatingSetPoint > 0 & LoadToCoolingSetPoint > 0 --> Heating required + // 2/ LoadToHeatingSetPoint > LoadToCoolingSetPoint --> Possible in the unmixed case but should be trapped + // as a poor choice of set-points + // 3/ LoadToHeatingSetPoint < 0 & LoadToCoolingSetPoint < 0 --> Cooling Required + // 4/ LoadToHeatingSetPoint <=0 & LoadToCoolingSetPoint >=0 --> Dead Band Operation ! includes zero load cases + // First trap bad set-points + if (LoadToHeatingSetPoint > LoadToCoolingSetPoint) { + ShowSevereError( + state, + "DataHVACGlobals::ThermostatType::SingleHeatCool: Effective heating set-point higher than effective cooling set-point - use " + "DualSetPointWithDeadBand if using unmixed air model"); + ShowContinueErrorTimeStamp(state, "occurs in Zone=" + thisZone.Name); + ShowContinueError(state, + format("LoadToHeatingSetPoint={:.3R}, LoadToCoolingSetPoint={:.3R}", LoadToHeatingSetPoint, LoadToCoolingSetPoint)); + ShowContinueError(state, format("Zone TempDepZnLd={:.2R}", this->TempDepZnLd)); + ShowContinueError(state, format("Zone TempIndZnLd={:.2R}", this->TempIndZnLd)); + ShowContinueError(state, format("Zone ThermostatSetPoint={:.2R}", thisTempZoneThermostatSetPoint)); + ShowFatalError(state, "Program terminates due to above conditions."); + } + + if (LoadToHeatingSetPoint > 0.0 && LoadToCoolingSetPoint > 0.0) { + totalLoad = LoadToHeatingSetPoint; + } else if (LoadToHeatingSetPoint < 0.0 && LoadToCoolingSetPoint < 0.0) { + totalLoad = LoadToCoolingSetPoint; + } else if (LoadToHeatingSetPoint <= 0.0 && LoadToCoolingSetPoint >= 0.0) { // deadband includes zero loads + totalLoad = 0.0; + if (thisZone.SystemZoneNodeNumber > 0) { + ZoneSetPoint = state.dataLoopNodes->Node(thisZone.SystemZoneNodeNumber).Temp; + ZoneSetPoint = max(ZoneSetPoint, thisZoneThermostatSetPointLo); // trap out of deadband + ZoneSetPoint = min(ZoneSetPoint, thisZoneThermostatSetPointHi); // trap out of deadband + } + thisDeadBandOrSetBack = true; + } else { // this should never occur! + ShowSevereError(state, + "SingleHeatCoolSetPoint: Unanticipated combination of heating and cooling loads - report to EnergyPlus Development Team"); + ShowContinueErrorTimeStamp(state, "occurs in Zone=" + thisZone.Name); + ShowContinueError(state, + format("LoadToHeatingSetPoint={:.3R}, LoadToCoolingSetPoint={:.3R}", LoadToHeatingSetPoint, LoadToCoolingSetPoint)); + ShowContinueError(state, format("Zone TempDepZnLd={:.2R}", this->TempDepZnLd)); + ShowContinueError(state, format("Zone TempIndZnLd={:.2R}", this->TempIndZnLd)); + ShowContinueError(state, format("Zone ThermostatSetPoint={:.2R}", thisTempZoneThermostatSetPoint)); + ShowFatalError(state, "Program terminates due to above conditions."); + } + break; + case DataHVACGlobals::ThermostatType::DualSetPointWithDeadBand: + switch (state.dataHeatBal->ZoneAirSolutionAlgo) { + case DataHeatBalance::SolutionAlgo::ThirdOrder: { + LoadToHeatingSetPoint = (this->TempDepZnLd * (thisZoneThermostatSetPointLo) - this->TempIndZnLd); + LoadToCoolingSetPoint = (this->TempDepZnLd * (thisZoneThermostatSetPointHi) - this->TempIndZnLd); + break; + } + case DataHeatBalance::SolutionAlgo::AnalyticalSolution: { + if (this->TempDepZnLd == 0.0) { // B=0 + LoadToHeatingSetPoint = this->AirPowerCap * (thisZoneThermostatSetPointLo - this->ZoneT1) - this->TempIndZnLd; + LoadToCoolingSetPoint = this->AirPowerCap * (thisZoneThermostatSetPointHi - this->ZoneT1) - this->TempIndZnLd; + } else { + Real64 const exp_700_TA(std::exp(min(700.0, -this->TempDepZnLd / this->AirPowerCap))); + LoadToHeatingSetPoint = + this->TempDepZnLd * (thisZoneThermostatSetPointLo - this->ZoneT1 * exp_700_TA) / (1.0 - exp_700_TA) - this->TempIndZnLd; + LoadToCoolingSetPoint = + this->TempDepZnLd * (thisZoneThermostatSetPointHi - this->ZoneT1 * exp_700_TA) / (1.0 - exp_700_TA) - this->TempIndZnLd; + } + break; + } + case DataHeatBalance::SolutionAlgo::EulerMethod: { + LoadToHeatingSetPoint = this->AirPowerCap * (thisZoneThermostatSetPointLo - this->ZoneT1) + + this->TempDepZnLd * thisZoneThermostatSetPointLo - this->TempIndZnLd; + LoadToCoolingSetPoint = this->AirPowerCap * (thisZoneThermostatSetPointHi - this->ZoneT1) + + this->TempDepZnLd * thisZoneThermostatSetPointHi - this->TempIndZnLd; + break; + } + default: { + assert(false); + } + } + if (RAFNFrac > 0.0) LoadToHeatingSetPoint = LoadToHeatingSetPoint / RAFNFrac; + if (RAFNFrac > 0.0) LoadToCoolingSetPoint = LoadToCoolingSetPoint / RAFNFrac; + + if (thisZone.HasAdjustedReturnTempByITE && !(state.dataGlobal->BeginSimFlag)) { + LoadToCoolingSetPoint = this->TempDepZnLd * thisZone.AdjustedReturnTempByITE - this->TempIndZnLd; + } + + // Possible combinations: + // 1/ LoadToHeatingSetPoint > 0 & LoadToCoolingSetPoint > 0 --> Heating required + // 2/ LoadToHeatingSetPoint > LoadToCoolingSetPoint --> Possible in the unmixed case but should be trapped + // as a poor choice of set-points + // 3/ LoadToHeatingSetPoint < 0 & LoadToCoolingSetPoint < 0 --> Cooling Required + // 4/ LoadToHeatingSetPoint <=0 & LoadToCoolingSetPoint >=0 --> Dead Band Operation - includes zero load cases + // First trap bad set-points + if (LoadToHeatingSetPoint > LoadToCoolingSetPoint) { + ShowSevereError(state, + "DualSetPointWithDeadBand: Effective heating set-point higher than effective cooling set-point - increase " + "deadband if using unmixed air model"); + ShowContinueErrorTimeStamp(state, "occurs in Zone=" + thisZone.Name); + ShowContinueError(state, + format("LoadToHeatingSetPoint={:.3R}, LoadToCoolingSetPoint={:.3R}", LoadToHeatingSetPoint, LoadToCoolingSetPoint)); + ShowContinueError(state, format("Zone TempDepZnLd={:.2R}", this->TempDepZnLd)); + ShowContinueError(state, format("Zone TempIndZnLd={:.2R}", this->TempIndZnLd)); + ShowContinueError(state, format("Zone Heating ThermostatSetPoint={:.2R}", thisZoneThermostatSetPointLo)); + ShowContinueError(state, format("Zone Cooling ThermostatSetPoint={:.2R}", thisZoneThermostatSetPointHi)); + ShowFatalError(state, "Program terminates due to above conditions."); + } + + if (LoadToHeatingSetPoint > 0.0 && LoadToCoolingSetPoint > 0.0) { + totalLoad = LoadToHeatingSetPoint; + ZoneSetPoint = thisZoneThermostatSetPointLo; + } else if (LoadToHeatingSetPoint < 0.0 && LoadToCoolingSetPoint < 0.0) { + totalLoad = LoadToCoolingSetPoint; + ZoneSetPoint = thisZoneThermostatSetPointHi; + } else if (LoadToHeatingSetPoint <= 0.0 && LoadToCoolingSetPoint >= 0.0) { // deadband includes zero loads + // this turns out to cause instabilities sometimes? that lead to setpoint errors if predictor is off. + totalLoad = 0.0; + if (thisZone.SystemZoneNodeNumber > 0) { + ZoneSetPoint = state.dataLoopNodes->Node(thisZone.SystemZoneNodeNumber).Temp; + ZoneSetPoint = max(ZoneSetPoint, thisZoneThermostatSetPointLo); // trap out of deadband + ZoneSetPoint = min(ZoneSetPoint, thisZoneThermostatSetPointHi); // trap out of deadband + } + thisDeadBandOrSetBack = true; + } else { // this should never occur! + ShowSevereError( + state, "DualSetPointWithDeadBand: Unanticipated combination of heating and cooling loads - report to EnergyPlus Development Team"); + ShowContinueErrorTimeStamp(state, "occurs in Zone=" + thisZone.Name); + ShowContinueError(state, + format("LoadToHeatingSetPoint={:.3R}, LoadToCoolingSetPoint={:.3R}", LoadToHeatingSetPoint, LoadToCoolingSetPoint)); + ShowContinueError(state, format("Zone Heating Set-point={:.2R}", thisZoneThermostatSetPointLo)); + ShowContinueError(state, format("Zone Cooling Set-point={:.2R}", thisZoneThermostatSetPointHi)); + ShowContinueError(state, format("Zone TempDepZnLd={:.2R}", this->TempDepZnLd)); + ShowContinueError(state, format("Zone TempIndZnLd={:.2R}", this->TempIndZnLd)); + ShowContinueError(state, format("Zone ThermostatSetPoint={:.2R}", thisTempZoneThermostatSetPoint)); + + ShowFatalError(state, "Program terminates due to above conditions."); + } + break; + default: + break; + } + + int systemNodeNumber = 0; + int stageNum = 0; + if (spaceNum > 0) { + systemNodeNumber = state.dataHeatBal->space(spaceNum).SystemZoneNodeNumber; + stageNum = state.dataZoneEnergyDemand->spaceSysEnergyDemand(spaceNum).StageNum; + assert(stageNum == state.dataZoneEnergyDemand->ZoneSysEnergyDemand(zoneNum).StageNum); + } else { + systemNodeNumber = thisZone.SystemZoneNodeNumber; + stageNum = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(zoneNum).StageNum; + } + // Staged control zone + if (state.dataZoneTempPredictorCorrector->NumStageCtrZone > 0) { + if (state.dataZoneCtrls->StageZoneLogic(zoneNum)) { + if (stageNum == 0) { // No load + LoadToHeatingSetPoint = 0.0; + LoadToCoolingSetPoint = 0.0; + totalLoad = 0.0; + if (systemNodeNumber > 0) { + ZoneSetPoint = state.dataLoopNodes->Node(systemNodeNumber).Temp; + ZoneSetPoint = max(ZoneSetPoint, thisZoneThermostatSetPointLo); // trap out of deadband + ZoneSetPoint = min(ZoneSetPoint, thisZoneThermostatSetPointHi); // trap out of deadband + } + thisDeadBandOrSetBack = true; + } else if (stageNum < 0) { // Cooling load + switch (state.dataHeatBal->ZoneAirSolutionAlgo) { + case DataHeatBalance::SolutionAlgo::ThirdOrder: { + LoadToCoolingSetPoint = (this->TempDepZnLd * (thisZoneThermostatSetPointHi) - this->TempIndZnLd); + break; + } + case DataHeatBalance::SolutionAlgo::AnalyticalSolution: { + if (this->TempDepZnLd == 0.0) { // B=0 + LoadToCoolingSetPoint = this->AirPowerCap * (thisZoneThermostatSetPointHi - this->ZoneT1) - this->TempIndZnLd; + } else { + Real64 const exp_700_TA(std::exp(min(700.0, -this->TempDepZnLd / this->AirPowerCap))); + LoadToCoolingSetPoint = + this->TempDepZnLd * (thisZoneThermostatSetPointHi - this->ZoneT1 * exp_700_TA) / (1.0 - exp_700_TA) - this->TempIndZnLd; + } + break; + } + case DataHeatBalance::SolutionAlgo::EulerMethod: { + LoadToCoolingSetPoint = this->AirPowerCap * (thisZoneThermostatSetPointHi - this->ZoneT1) + + this->TempDepZnLd * thisZoneThermostatSetPointHi - this->TempIndZnLd; + break; + } + default: { + assert(false); + } + } + totalLoad = LoadToCoolingSetPoint; + ZoneSetPoint = thisZoneThermostatSetPointHi; + LoadToHeatingSetPoint = LoadToCoolingSetPoint; + if ((totalLoad) >= 0.0) thisDeadBandOrSetBack = true; + } else { // Heating load + switch (state.dataHeatBal->ZoneAirSolutionAlgo) { + case DataHeatBalance::SolutionAlgo::ThirdOrder: { + LoadToHeatingSetPoint = (this->TempDepZnLd * thisZoneThermostatSetPointLo - this->TempIndZnLd); + break; + } + case DataHeatBalance::SolutionAlgo::AnalyticalSolution: { + if (this->TempDepZnLd == 0.0) { // B=0 + LoadToHeatingSetPoint = this->AirPowerCap * (thisZoneThermostatSetPointLo - this->ZoneT1) - this->TempIndZnLd; + } else { + Real64 const exp_700_TA(std::exp(min(700.0, -this->TempDepZnLd / this->AirPowerCap))); + LoadToHeatingSetPoint = + this->TempDepZnLd * (thisZoneThermostatSetPointLo - this->ZoneT1 * exp_700_TA) / (1.0 - exp_700_TA) - this->TempIndZnLd; + } + break; + } + case DataHeatBalance::SolutionAlgo::EulerMethod: { + LoadToHeatingSetPoint = this->AirPowerCap * (thisZoneThermostatSetPointLo - this->ZoneT1) + + this->TempDepZnLd * (thisZoneThermostatSetPointLo) - this->TempIndZnLd; + break; + } + default: { + assert(false); + } + } + totalLoad = LoadToHeatingSetPoint; + ZoneSetPoint = thisZoneThermostatSetPointLo; + LoadToCoolingSetPoint = LoadToHeatingSetPoint; + if ((totalLoad) <= 0.0) thisDeadBandOrSetBack = true; + } + } + } + + // If the ZoneNodeNum has been set for a Controlled Zone, then the zone setpoint is placed on the node. + if (thisZone.SystemZoneNodeNumber > 0) { + state.dataLoopNodes->Node(thisZone.SystemZoneNodeNumber).TempSetPoint = ZoneSetPoint; + } + + state.dataZoneEnergyDemand->Setback(zoneNum) = (ZoneSetPoint > this->ZoneSetPointLast); + + this->ZoneSetPointLast = ZoneSetPoint; + state.dataHeatBalFanSys->TempZoneThermostatSetPoint(zoneNum) = ZoneSetPoint; // needed to fix Issue # 5048 + state.dataZoneEnergyDemand->DeadBandOrSetback(zoneNum) = thisDeadBandOrSetBack; + state.dataZoneEnergyDemand->CurDeadBandOrSetback(zoneNum) = thisDeadBandOrSetBack; + + // Apply the Zone Multiplier and Load Correction factor as needed + if (spaceNum > 0) { + state.dataZoneEnergyDemand->spaceSysEnergyDemand(spaceNum).reportSensibleLoadsZoneMultiplier( + state, zoneNum, totalLoad, LoadToHeatingSetPoint, LoadToCoolingSetPoint); + } else { + state.dataZoneEnergyDemand->ZoneSysEnergyDemand(zoneNum).reportSensibleLoadsZoneMultiplier( + state, zoneNum, totalLoad, LoadToHeatingSetPoint, LoadToCoolingSetPoint); + } +} } // namespace EnergyPlus::ZoneTempPredictorCorrector diff --git a/src/EnergyPlus/ZoneTempPredictorCorrector.hh b/src/EnergyPlus/ZoneTempPredictorCorrector.hh index f12d29ac67a..01721743896 100644 --- a/src/EnergyPlus/ZoneTempPredictorCorrector.hh +++ b/src/EnergyPlus/ZoneTempPredictorCorrector.hh @@ -61,6 +61,7 @@ #include #include #include +#include #include namespace EnergyPlus { @@ -104,6 +105,174 @@ namespace ZoneTempPredictorCorrector { Array1D ThermalComfortAdaptiveCEN15251_Central; }; + struct SumHATOutput + { + // Output results from calSumHAT + Real64 sumIntGain = 0.0; + Real64 sumHA = 0.0; + Real64 sumHATsurf = 0.0; + Real64 sumHATref = 0.0; + }; + + struct ZoneSpaceHeatBalanceData + { + // This entire struct is re-initialized during the simulation, so no static data may be stored here (e.g. zone or space characteristics) + + // Zone or space air drybulb temperature conditions + Real64 MAT = DataHeatBalance::ZoneInitialTemp; // Mean Air Temperature at end of zone time step [C] + Real64 ZTAV = DataHeatBalance::ZoneInitialTemp; // Air Temperature Averaged over the zone time step (during HVAC Time Steps) + Real64 ZT = DataHeatBalance::ZoneInitialTemp; // Air Temperature Averaged over the system time step + Real64 ZTAVComf = DataHeatBalance::ZoneInitialTemp; // Air Temperature Averaged used in thermal comfort models (currently Fanger model only) - + // TODO: lagged? could MAT be used instead? + Real64 XMPT = DataHeatBalance::ZoneInitialTemp; // Air temperature at previous system time step + std::array XMAT = {DataHeatBalance::ZoneInitialTemp, + DataHeatBalance::ZoneInitialTemp, + DataHeatBalance::ZoneInitialTemp, + DataHeatBalance::ZoneInitialTemp}; // Temporary air temperature history + std::array DSXMAT = {DataHeatBalance::ZoneInitialTemp, + DataHeatBalance::ZoneInitialTemp, + DataHeatBalance::ZoneInitialTemp, + DataHeatBalance::ZoneInitialTemp}; // Down Stepped air temperature history storage + // Exact and Euler solutions + Real64 ZoneTMX = DataHeatBalance::ZoneInitialTemp; // Temporary air temperature to test convergence in Exact and Euler method + Real64 ZoneTM2 = DataHeatBalance::ZoneInitialTemp; // Temporary air temperature at timestep t-2 in Exact and Euler method + Real64 ZoneT1 = 0.0; // Air temperature at the previous time step used in Exact and Euler method + + // Zone or space air moisture conditions + Real64 ZoneAirHumRat = 0.01; // Air Humidity Ratio + Real64 ZoneAirHumRatAvg = 0.01; // Air Humidity Ratio averaged over the zone time step + Real64 ZoneAirHumRatTemp = 0.01; // Temporary air humidity ratio at time plus 1 + Real64 ZoneAirHumRatAvgComf = 0.01; // Air Humidity Ratio averaged over the zone time + // step used in thermal comfort models (currently Fang model only) + // TODO: lagged? could ZoneAirHumRatAvg be used instead? + + std::array WPrevZoneTS = {0.0, 0.0, 0.0, 0.0}; // Air Humidity Ratio zone time step history + std::array DSWPrevZoneTS = {0.0, 0.0, 0.0, 0.0}; // DownStepped Air Humidity Ratio zone time step history for 3rd order derivative + Real64 WZoneTimeMinusP = 0.0; // Air Humidity Ratio at previous system time step + // Exact and Euler solutions + Real64 ZoneWMX = 0.0; // Temporary humidity ratio to test convergence in Exact and Euler method + Real64 ZoneWM2 = 0.0; // Temporary humidity ratio at timestep t-2 in Exact and Euler method + Real64 ZoneW1 = 0.0; // Zone/space humidity ratio at the previous time step used in Exact and Euler method + + std::array ZTM = { + 0.0, 0.0, 0.0, 0.0}; // air temperature at previous 3 zone timesteps (sized to 4 to be compatible with other similar arrays) + std::array WPrevZoneTSTemp = {0.0, 0.0, 0.0, 0.0}; // Temporary Air Humidity Ratio zone time step history (4th term not used) + // Real64 WZoneTimeMinus1Temp = 0.0; // Zone air humidity ratio at previous timestep + // Real64 WZoneTimeMinus2Temp = 0.0; // Zone air humidity ratio at timestep T-2 + // Real64 WZoneTimeMinus3Temp = 0.0; // Zone air humidity ratio at timestep T-3 + + Real64 SumIntGain = 0.0; // Sum of convective internal gains + Real64 SumHA = 0.0; // Sum of Hc*Area + Real64 SumHATsurf = 0.0; // Sum of Hc*Area*Tsurf + Real64 SumHATref = 0.0; // Sum of Hc*Area*Tref= 0.0; for ceiling diffuser convection correlation + Real64 SumMCp = 0.0; // Sum of MassFlowRate*Cp + Real64 SumMCpT = 0.0; // Sum of MassFlowRate*Cp*T + Real64 SumSysMCp = 0.0; // Sum of air system MassFlowRate*Cp + Real64 SumSysMCpT = 0.0; // Sum of air system MassFlowRate*Cp*T + Real64 SumIntGainExceptPeople = 0.0; + + // Moisture variables to carry info from HB to the Zone Temp Predictor-Corrector for Fan System + Real64 SumHmAW = 0.0; // SUM OF ZONE AREA*Moist CONVECTION COEFF*INSIDE Humidity Ratio + Real64 SumHmARa = 0.0; // SUM OF ZONE AREA*Moist CONVECTION COEFF*Rho Air + Real64 SumHmARaW = 0.0; // SUM OF ZONE AREA*Moist CONVECTION COEFF*Rho Air* Inside Humidity Ration + Real64 SumHmARaZ = 0.0; + + Real64 TempDepCoef = 0.0; // Temperature dependent coefficient + Real64 TempIndCoef = 0.0; // Temperature ndependent coefficient + Real64 TempHistoryTerm = 0.0; + + Real64 MCPI = 0.0; // INFILTRATION MASS FLOW * AIR SPECIFIC HEAT + Real64 MCPTI = 0.0; // INFILTRATION MASS FLOW * AIR CP * AIR TEMPERATURE + Real64 MCPV = 0.0; // VENTILATION MASS FLOW * AIR SPECIFIC HEAT + Real64 MCPTV = 0.0; // VENTILATION MASS FLOW * AIR CP * AIR TEMPERATURE + Real64 MCPM = 0.0; // Mixing MASS FLOW * AIR SPECIFIC HEAT + Real64 MCPTM = 0.0; // Mixing MASS FLOW * AIR CP * AIR TEMPERATURE + Real64 MCPE = 0.0; // EARTHTUBE MASS FLOW * AIR SPECIFIC HEAT + Real64 EAMFL = 0.0; // OUTDOOR AIR MASS FLOW for EarthTube + Real64 EAMFLxHumRat = 0.0; // OUTDOOR AIR MASS FLOW * Humidity Ratio for EarthTube (water vapor mass flow) + Real64 MCPTE = 0.0; // EARTHTUBE MASS FLOW * AIR CP * AIR TEMPERATURE + Real64 MCPC = 0.0; // COOLTOWER MASS FLOW * AIR SPECIFIC HEAT + Real64 CTMFL = 0.0; // OUTDOOR AIR MASS FLOW for cooltower + Real64 MCPTC = 0.0; // COOLTOWER MASS FLOW * AIR CP * AIR TEMPERATURE + Real64 ThermChimAMFL = 0.0; // OUTDOOR AIR MASS FLOW for THERMALCHIMNEY + Real64 MCPTThermChim = 0.0; // THERMALCHIMNEY MASS FLOW * AIR SPECIFIC HEAT + Real64 MCPThermChim = 0.0; // THERMALCHIMNEY MASS FLOW * AIR CP * AIR TEMPERATURE + Real64 ZoneLatentGain = 0.0; // Latent Energy from each Zone (People, equipment) + Real64 ZoneLatentGainExceptPeople = 0.0; // Added for hybrid model -- Latent Energy from each Zone (equipment) + Real64 OAMFL = 0.0; // OUTDOOR AIR MASS FLOW (kg/s) for infiltration + Real64 VAMFL = 0.0; // OUTDOOR AIR MASS FLOW (kg/s) for ventilation + Real64 NonAirSystemResponse = 0.0; // Convective heat addition rate from non forced air + // equipment such as baseboards plus heat from lights to + Real64 SysDepZoneLoads = 0.0; // Convective heat addition or subtraction rate from sources that + // depend on what is happening with the HVAC system. Such as: + // heat gain from lights to return air when return flow = 0= 0.0; heat gain + // from air flow windows to return air when return air flow = 0= 0.0; + // and heat removed by return air from refrigeration cases when + // return air flow = 0. + Real64 SysDepZoneLoadsLagged = 0.0; // SysDepZoneLoads saved to be added to zone heat balance next + // HVAC time step + Real64 MDotCPOA = 0.0; // Airbalance MASS FLOW * AIR SPECIFIC HEAT used at Air Balance Method = Quadrature in the ZoneAirBalance:OutdoorAir + Real64 MDotOA = 0.0; // Airbalance MASS FLOW rate used at Air Balance Method = Quadrature in the ZoneAirBalance:OutdoorAir + Real64 MixingMAT = DataHeatBalance::ZoneInitialTemp; // Air temperature for mixing + Real64 MixingHumRat = 0.01; // Air humidity ratio for mixing + Real64 MixingMassFlowZone = 0.0; // Mixing MASS FLOW (kg/s) + Real64 MixingMassFlowXHumRat = 0.0; // Mixing MASS FLOW * Humidity Ratio + + Real64 ZoneSetPointLast = 0.0; + Real64 TempIndZnLd = 0.0; + Real64 TempDepZnLd = 0.0; + Real64 ZoneAirRelHum = 0.0; // Zone relative humidity in percent + Real64 AirPowerCap = 0.0; // "air power capacity" Vol*VolMult*rho*Cp/timestep [W/degK] + + void beginEnvironmentInit(EnergyPlusData &state); + + void setUpOutputVars(EnergyPlusData &state, std::string_view prefix, std::string_view name); + + void predictSystemLoad(EnergyPlusData &state, + bool shortenTimeStepSys, + bool useZoneTimeStepHistory, // if true then use zone timestep history, if false use system time step + Real64 priorTimeStep, // the old value for timestep length is passed for possible use in interpolating + int zoneNum, + int spaceNum = 0); + + void calcPredictedSystemLoad(EnergyPlusData &state, Real64 RAFNFrac, int zoneNum, int spaceNum = 0); + + void calcZoneOrSpaceSums(EnergyPlusData &state, + bool CorrectorFlag, // Corrector call flag + int zoneNum, + int spaceNum = 0); + + virtual SumHATOutput calcSumHAT(EnergyPlusData &state, int zoneNum, int spaceNum) = 0; + + void updateTemperatures( + EnergyPlusData &state, bool ShortenTimeStepSys, bool UseZoneTimeStepHistory, Real64 PriorTimeStep, int zoneNum, int spaceNum = 0); + + Real64 correctAirTemp(EnergyPlusData &state, + bool useZoneTimeStepHistory, // if true then use zone timestep history, if false use system time step history + int zoneNum, + int spaceNum = 0); + + void correctHumRat(EnergyPlusData &state, int zoneNum, int spaceNum = 0); + + void calcPredictedHumidityRatio(EnergyPlusData &state, Real64 RAFNFrac, int zoneNum, int spaceNum = 0); + + void pushZoneTimestepHistory(EnergyPlusData &state, int zoneNum, int spaceNum = 0); + + void pushSystemTimestepHistory(EnergyPlusData &state, int zoneNum, int spaceNum = 0); + + void revertZoneTimestepHistory(EnergyPlusData &state, int zoneNum, int spaceNum = 0); + }; + + struct ZoneHeatBalanceData : ZoneSpaceHeatBalanceData + { + SumHATOutput calcSumHAT(EnergyPlusData &state, int zoneNum, [[maybe_unused]] int spaceNum) override; + }; + + struct SpaceHeatBalanceData : ZoneSpaceHeatBalanceData + { + SumHATOutput calcSumHAT(EnergyPlusData &state, int zoneNum, int spaceNum) override; + }; + // Functions void ManageZoneAirUpdates(EnergyPlusData &state, @@ -131,34 +300,8 @@ namespace ZoneTempPredictorCorrector { void CalculateAdaptiveComfortSetPointSchl(EnergyPlusData &state, Array1D const &runningAverageASH, Array1D const &runningAverageCEN); - void CalcPredictedSystemLoad(EnergyPlusData &state, int ZoneNum, Real64 RAFNFrac); - - void ReportSensibleLoadsZoneMultiplier(Real64 &TotalLoad, - Real64 &TotalHeatLoad, - Real64 &TotalCoolLoad, - Real64 &SensLoadSingleZone, - Real64 &SensLoadHeatSingleZone, - Real64 &SensLoadCoolSingleZone, - Real64 OutputHeatSP, - Real64 OutputCoolSP, - Real64 LoadCorrFactor, - Real64 ZoneMultiplier, - Real64 ZoneMultiplierList); - - void CalcPredictedHumidityRatio(EnergyPlusData &state, int ZoneNum, Real64 RAFNFrac); - - void ReportMoistLoadsZoneMultiplier(Real64 &TotalLoad, - Real64 &TotalHumidLoad, - Real64 &TotalDehumidLoad, - Real64 &MoistLoadSingleZone, - Real64 &MoistLoadHumidSingleZone, - Real64 &MoistLoadDehumidSingleZone, - Real64 ZoneMultiplier, - Real64 ZoneMultiplierList); - - void CorrectZoneAirTemp(EnergyPlusData &state, - Real64 &ZoneTempChange, // Temperature change in zone air between previous and current timestep - bool UseZoneTimeStepHistory // if true then use zone timestep history, if false use system time step history + Real64 correctZoneAirTemps(EnergyPlusData &state, + bool useZoneTimeStepHistory // if true then use zone timestep history, if false use system time step history ); void PushZoneTimestepHistories(EnergyPlusData &state); @@ -167,55 +310,42 @@ namespace ZoneTempPredictorCorrector { void RevertZoneTimestepHistories(EnergyPlusData &state); - void CorrectZoneHumRat(EnergyPlusData &state, int ZoneNum); - void DownInterpolate4HistoryValues(Real64 OldTimeStep, Real64 NewTimeStep, - Real64 &oldVal0, - Real64 &oldVal1, - Real64 &oldVal2, + Real64 oldVal0, + Real64 oldVal1, + Real64 oldVal2, Real64 &newVal0, Real64 &newVal1, Real64 &newVal2, - Real64 &newVal3, // unused 1208 - Real64 &newVal4 // unused 1208 - ); + Real64 &newVal3, + Real64 &newVal4); + + Real64 + DownInterpolate4HistoryValues(Real64 OldTimeStep, Real64 NewTimeStep, std::array const &oldVals, std::array &newVals); void InverseModelTemperature(EnergyPlusData &state, - int ZoneNum, // Zone number - Real64 &SumIntGain, // Zone sum of convective internal gains - Real64 &SumIntGainExceptPeople, // Zone sum of convective internal gains except for people - Real64 &SumHA, // Zone sum of Hc*Area - Real64 &SumHATsurf, // Zone sum of Hc*Area*Tsurf - Real64 &SumHATref, // Zone sum of Hc*Area*Tref, for ceiling diffuser convection correlation - Real64 &SumMCp, // Zone sum of MassFlowRate*Cp - Real64 &SumMCpT, // Zone sum of MassFlowRate*Cp*T - Real64 &SumSysMCp, // Zone sum of air system MassFlowRate*Cp - Real64 &SumSysMCpT, // Zone sum of air system MassFlowRate*Cp*T - Real64 &AirCap // Formerly CoefAirrat, coef in zone temp eqn with dim of "air power capacity"rd + int ZoneNum, // Zone number + Real64 SumIntGain, // Zone sum of convective internal gains + Real64 SumIntGainExceptPeople, // Zone sum of convective internal gains except for people + Real64 SumHA, // Zone sum of Hc*Area + Real64 SumHATsurf, // Zone sum of Hc*Area*Tsurf + Real64 SumHATref, // Zone sum of Hc*Area*Tref, for ceiling diffuser convection correlation + Real64 SumMCp, // Zone sum of MassFlowRate*Cp + Real64 SumMCpT, // Zone sum of MassFlowRate*Cp*T + Real64 SumSysMCp, // Zone sum of air system MassFlowRate*Cp + Real64 SumSysMCpT, // Zone sum of air system MassFlowRate*Cp*T + Real64 AirCap // Formerly CoefAirrat, coef in zone temp eqn with dim of "air power capacity"rd ); void InverseModelHumidity(EnergyPlusData &state, - int ZoneNum, // Zone number - Real64 &LatentGain, // Zone sum of latent gain - Real64 &LatentGainExceptPeople, // Zone sum of latent gain except for people - Real64 &ZoneMassFlowRate, // Zone air mass flow rate - Real64 &MoistureMassFlowRate, // Zone moisture mass flow rate - Real64 &H2OHtOfVap, // Heat of vaporization of air - Real64 &RhoAir // Air density - ); - - void CalcZoneSums(EnergyPlusData &state, - int ZoneNum, // Zone number - Real64 &SumIntGain, // Zone sum of convective internal gains - Real64 &SumHA, // Zone sum of Hc*Area - Real64 &SumHATsurf, // Zone sum of Hc*Area*Tsurf - Real64 &SumHATref, // Zone sum of Hc*Area*Tref, for ceiling diffuser convection correlation - Real64 &SumMCp, // Zone sum of MassFlowRate*Cp - Real64 &SumMCpT, // Zone sum of MassFlowRate*Cp*T - Real64 &SumSysMCp, // Zone sum of air system MassFlowRate*Cp - Real64 &SumSysMCpT, // Zone sum of air system MassFlowRate*Cp*T - bool CorrectorFlag = true // Corrector call flag + int ZoneNum, // Zone number + Real64 LatentGain, // Zone sum of latent gain + Real64 LatentGainExceptPeople, // Zone sum of latent gain except for people + Real64 ZoneMassFlowRate, // Zone air mass flow rate + Real64 MoistureMassFlowRate, // Zone moisture mass flow rate + Real64 H2OHtOfVap, // Heat of vaporization of air + Real64 RhoAir // Air density ); void CalcZoneComponentLoadSums(EnergyPlusData &state, @@ -285,11 +415,6 @@ struct ZoneTempPredictorCorrectorData : BaseGlobalStruct // Number of zone with onoff thermostat int NumOnOffCtrZone = 0; - Array1D ZoneSetPointLast; - Array1D TempIndZnLd; - Array1D TempDepZnLd; - Array1D ZoneAirRelHum; // Zone relative humidity in percent - // Zone temperature history - used only for oscillation test Array2D ZoneTempHist; Array1D ZoneTempOscillate; @@ -331,6 +456,9 @@ struct ZoneTempPredictorCorrectorData : BaseGlobalStruct int IterLimitExceededNum2 = 0; int IterLimitErrIndex2 = 0; + EPVector zoneHeatBalance; + EPVector spaceHeatBalance; + void clear_state() override { *this = ZoneTempPredictorCorrectorData(); diff --git a/testfiles/5ZoneAirCooledWithSpaceHeatBalance.idf b/testfiles/5ZoneAirCooledWithSpaceHeatBalance.idf new file mode 100644 index 00000000000..01a19224717 --- /dev/null +++ b/testfiles/5ZoneAirCooledWithSpaceHeatBalance.idf @@ -0,0 +1,3569 @@ +!-Generator IDFEditor 1.34 +!-Option OriginalOrderTop UseSpecialFormat +!-NOTE: All comments with '!-' are ignored by the IDFEditor and are generated automatically. +!- Use '!' comments if they need to be retained when using the IDFEditor. +! 5ZoneAirCooledWithSpaceHeatBalance.idf +! Basic file description: 1 story building divided into 4 exterior and one interior conditioned zones and return plenum. +! +! Highlights: Electric chiller with air cooled condenser; autosized preheating and precooling water coils in the +! outside air stream controlled to preheat and precool setpoints. +! +! Simulation Location/Run: CHICAGO_IL_USA TMY2-94846, 2 design days, 2 run periods, +! Run Control executes the run periods using the weather file +! +! Location: Chicago, IL +! +! Design Days: CHICAGO_IL_USA Annual Heating 99% Design Conditions DB, MaxDB= -17.3°C +! CHICAGO_IL_USA Annual Cooling 1% Design Conditions, MaxDB= 31.5°C MCWB= 23.0°C +! +! Run Period (Weather File): 1/1 through 12/31, CHICAGO_IL_USA TMY2-94846 +! +! Run Control: Zone and System sizing with weather file run control (no design days run) +! +! Building: Single floor rectangular building 100 ft x 50 ft. 5 zones - 4 exterior, 1 interior, zone height 8 feet. +! Exterior zone depth is 12 feet. There is a 2 foot high return plenum: the overall building height is +! 10 feet. There are windows on all 4 facades; the south and north facades have glass doors. +! The south facing glass is shaded by overhangs. The walls are woodshingle over plywood, R11 insulation, +! and gypboard. The roof is a gravel built up roof with R-3 mineral board insulation and plywood sheathing. +! The windows are of various single and double pane construction with 3mm and 6mm glass and either 6mm or +! 13mm argon or air gap. The window to wall ratio is approximately 0.29. +! The south wall and door have overhangs. +! +! The building is oriented 30 degrees east of north. +! +! Floor Area: 463.6 m2 (5000 ft2) +! Number of Stories: 1 +! +! Zone Description Details: +! +! (0,15.2,0) (30.5,15.2,0) +! _____ ________ ____ +! |\ *** **************** /| +! | \ / | +! | \ (26.8,11.6,0) / | +! * \_____________________________/ * +! * |(3.7,11.6,0) | * +! * | | * +! * | | * +! * | (26.8,3.7,0)| * +! * |___________________________| * +! * / (3.7,3.7,0) \ * +! | / \ | +! | / \ | +! |/___******************___***________\| +! | Overhang | | +! |_______________________| | window/door = * +! |___| +! +! (0,0,0) (30.5,0,0) +! +! Internal gains description: lighting is 1.5 watts/ft2, office equip is 1.0 watts/ft2. There is 1 occupant +! per 100 ft2 of floor area. The infiltration is 0.25 air changes per hour. +! +! Interzone Surfaces: 6 interzone surfaces (see diagram) +! Internal Mass: None +! People: 50 +! Lights: 7500 W +! Windows: 4 ea.: 1) Double pane clear, 3mm glass, 13mm air gap +! 2) Double pane clear, 3mm glass, 13mm argon gap +! 3) Double pane clear, 6mm glass, 6mm air gap +! 4) Double pane lowE, 6mm lowE glass outside, 6mm air gap, 6mm clear glass +! +! Doors: 2 ea.: Single pane grey, 3mm glass +! +! Detached Shading: None +! Daylight: None +! Natural Ventilation: None +! Compact Schedules: Yes +! +! HVAC: Standard VAV system with outside air, hot water reheat coils, +! central chilled water cooling coil. Central Plant is single hot water +! boiler, electric compression chiller with air cooled condenser. +! All equipment is autosized. HW and ChW coils are used in the outside air +! stream to precondition the outside air. +! +! Zonal Equipment: AirTerminal:SingleDuct:VAV:Reheat +! Central Air Handling Equipment: Yes +! System Equipment Autosize: Yes +! Purchased Cooling: None +! Purchased Heating: None +! Coils: Coil:Cooling:Water, Coil:Heating:Water +! Pumps: Pump:VariableSpeed +! Boilers: Boiler:HotWater +! Chillers: Chiller:Electric +! +! Results: +! Standard Reports: None +! Timestep or Hourly Variables: Hourly +! Time bins Report: None +! HTML Report: None +! Environmental Emissions: None +! Utility Tariffs: None + + Version,22.2; + + Building, + Building, !- Name + 30., !- North Axis {deg} + City, !- Terrain + 0.04, !- Loads Convergence Tolerance Value {W} + 0.4, !- Temperature Convergence Tolerance Value {deltaC} + FullExterior, !- Solar Distribution + 25, !- Maximum Number of Warmup Days + 6; !- Minimum Number of Warmup Days + + Timestep,4; + + SurfaceConvectionAlgorithm:Inside,Simple; + + SurfaceConvectionAlgorithm:Outside,SimpleCombined; + + HeatBalanceAlgorithm,ConductionTransferFunction; + +ZoneAirHeatBalanceAlgorithm, + ThirdOrderBackwardDifference, !- Algorithm + Yes, !- Do Space Heat Balance for Sizing + Yes; !- Do Space Heat Balance for Simulation + + GlobalGeometryRules, + UpperLeftCorner, !- Starting Vertex Position + CounterClockWise, !- Vertex Entry Direction + Relative; !- Coordinate System + + ScheduleTypeLimits, + Any Number; !- Name + + ScheduleTypeLimits, + Fraction, !- Name + 0.0, !- Lower Limit Value + 1.0, !- Upper Limit Value + CONTINUOUS; !- Numeric Type + + ScheduleTypeLimits, + Temperature, !- Name + -60, !- Lower Limit Value + 200, !- Upper Limit Value + CONTINUOUS, !- Numeric Type + Temperature; !- Unit Type + + ScheduleTypeLimits, + Control Type, !- Name + 0, !- Lower Limit Value + 4, !- Upper Limit Value + DISCRETE; !- Numeric Type + + ScheduleTypeLimits, + On/Off, !- Name + 0, !- Lower Limit Value + 1, !- Upper Limit Value + DISCRETE; !- Numeric Type + + ScheduleTypeLimits, + FlowRate, !- Name + 0.0, !- Lower Limit Value + 10, !- Upper Limit Value + CONTINUOUS; !- Numeric Type + + RunPeriod, + Run Period 1, !- Name + 1, !- Begin Month + 1, !- Begin Day of Month + , !- Begin Year + 12, !- End Month + 31, !- End Day of Month + , !- End Year + Tuesday, !- Day of Week for Start Day + Yes, !- Use Weather File Holidays and Special Days + Yes, !- Use Weather File Daylight Saving Period + No, !- Apply Weekend Holiday Rule + Yes, !- Use Weather File Rain Indicators + Yes; !- Use Weather File Snow Indicators + + Site:Location, + CHICAGO_IL_USA TMY2-94846, !- Name + 41.78, !- Latitude {deg} + -87.75, !- Longitude {deg} + -6.00, !- Time Zone {hr} + 190.00; !- Elevation {m} + + SimulationControl, + Yes, !- Do Zone Sizing Calculation + Yes, !- Do System Sizing Calculation + Yes, !- Do Plant Sizing Calculation + No, !- Run Simulation for Sizing Periods + Yes, !- Run Simulation for Weather File Run Periods + No, !- Do HVAC Sizing Simulation for Sizing Periods + 1; !- Maximum Number of HVAC Sizing Simulation Passes + +! CHICAGO_IL_USA Annual Heating 99% Design Conditions DB, MaxDB= -17.3°C + + SizingPeriod:DesignDay, + CHICAGO_IL_USA Annual Heating 99% Design Conditions DB, !- Name + 1, !- Month + 21, !- Day of Month + WinterDesignDay, !- Day Type + -17.3, !- Maximum Dry-Bulb Temperature {C} + 0.0, !- Daily Dry-Bulb Temperature Range {deltaC} + , !- Dry-Bulb Temperature Range Modifier Type + , !- Dry-Bulb Temperature Range Modifier Day Schedule Name + Wetbulb, !- Humidity Condition Type + -17.3, !- Wetbulb or DewPoint at Maximum Dry-Bulb {C} + , !- Humidity Condition Day Schedule Name + , !- Humidity Ratio at Maximum Dry-Bulb {kgWater/kgDryAir} + , !- Enthalpy at Maximum Dry-Bulb {J/kg} + , !- Daily Wet-Bulb Temperature Range {deltaC} + 99063., !- Barometric Pressure {Pa} + 4.9, !- Wind Speed {m/s} + 270, !- Wind Direction {deg} + No, !- Rain Indicator + No, !- Snow Indicator + No, !- Daylight Saving Time Indicator + ASHRAEClearSky, !- Solar Model Indicator + , !- Beam Solar Day Schedule Name + , !- Diffuse Solar Day Schedule Name + , !- ASHRAE Clear Sky Optical Depth for Beam Irradiance (taub) {dimensionless} + , !- ASHRAE Clear Sky Optical Depth for Diffuse Irradiance (taud) {dimensionless} + 0.0; !- Sky Clearness + +! CHICAGO_IL_USA Annual Cooling 1% Design Conditions, MaxDB= 31.5°C MCWB= 23.0°C + + SizingPeriod:DesignDay, + CHICAGO_IL_USA Annual Cooling 1% Design Conditions DB/MCWB, !- Name + 7, !- Month + 21, !- Day of Month + SummerDesignDay, !- Day Type + 31.5, !- Maximum Dry-Bulb Temperature {C} + 10.7, !- Daily Dry-Bulb Temperature Range {deltaC} + , !- Dry-Bulb Temperature Range Modifier Type + , !- Dry-Bulb Temperature Range Modifier Day Schedule Name + Wetbulb, !- Humidity Condition Type + 23.0, !- Wetbulb or DewPoint at Maximum Dry-Bulb {C} + , !- Humidity Condition Day Schedule Name + , !- Humidity Ratio at Maximum Dry-Bulb {kgWater/kgDryAir} + , !- Enthalpy at Maximum Dry-Bulb {J/kg} + , !- Daily Wet-Bulb Temperature Range {deltaC} + 99063., !- Barometric Pressure {Pa} + 5.3, !- Wind Speed {m/s} + 230, !- Wind Direction {deg} + No, !- Rain Indicator + No, !- Snow Indicator + No, !- Daylight Saving Time Indicator + ASHRAEClearSky, !- Solar Model Indicator + , !- Beam Solar Day Schedule Name + , !- Diffuse Solar Day Schedule Name + , !- ASHRAE Clear Sky Optical Depth for Beam Irradiance (taub) {dimensionless} + , !- ASHRAE Clear Sky Optical Depth for Diffuse Irradiance (taud) {dimensionless} + 1.0; !- Sky Clearness + + Site:GroundTemperature:BuildingSurface,20.03,20.03,20.13,20.30,20.43,20.52,20.62,20.77,20.78,20.55,20.44,20.20; + + Material, + WD10, !- Name + MediumSmooth, !- Roughness + 0.667, !- Thickness {m} + 0.115, !- Conductivity {W/m-K} + 513, !- Density {kg/m3} + 1381, !- Specific Heat {J/kg-K} + 0.9, !- Thermal Absorptance + 0.78, !- Solar Absorptance + 0.78; !- Visible Absorptance + + Material, + RG01, !- Name + Rough, !- Roughness + 1.2700000E-02, !- Thickness {m} + 1.442000, !- Conductivity {W/m-K} + 881.0000, !- Density {kg/m3} + 1674.000, !- Specific Heat {J/kg-K} + 0.9000000, !- Thermal Absorptance + 0.6500000, !- Solar Absorptance + 0.6500000; !- Visible Absorptance + + Material, + BR01, !- Name + VeryRough, !- Roughness + 9.4999997E-03, !- Thickness {m} + 0.1620000, !- Conductivity {W/m-K} + 1121.000, !- Density {kg/m3} + 1464.000, !- Specific Heat {J/kg-K} + 0.9000000, !- Thermal Absorptance + 0.7000000, !- Solar Absorptance + 0.7000000; !- Visible Absorptance + + Material, + IN46, !- Name + VeryRough, !- Roughness + 7.6200001E-02, !- Thickness {m} + 2.3000000E-02, !- Conductivity {W/m-K} + 24.00000, !- Density {kg/m3} + 1590.000, !- Specific Heat {J/kg-K} + 0.9000000, !- Thermal Absorptance + 0.5000000, !- Solar Absorptance + 0.5000000; !- Visible Absorptance + + Material, + WD01, !- Name + MediumSmooth, !- Roughness + 1.9099999E-02, !- Thickness {m} + 0.1150000, !- Conductivity {W/m-K} + 513.0000, !- Density {kg/m3} + 1381.000, !- Specific Heat {J/kg-K} + 0.9000000, !- Thermal Absorptance + 0.7800000, !- Solar Absorptance + 0.7800000; !- Visible Absorptance + + Material, + PW03, !- Name + MediumSmooth, !- Roughness + 1.2700000E-02, !- Thickness {m} + 0.1150000, !- Conductivity {W/m-K} + 545.0000, !- Density {kg/m3} + 1213.000, !- Specific Heat {J/kg-K} + 0.9000000, !- Thermal Absorptance + 0.7800000, !- Solar Absorptance + 0.7800000; !- Visible Absorptance + + Material, + IN02, !- Name + Rough, !- Roughness + 9.0099998E-02, !- Thickness {m} + 4.3000001E-02, !- Conductivity {W/m-K} + 10.00000, !- Density {kg/m3} + 837.0000, !- Specific Heat {J/kg-K} + 0.9000000, !- Thermal Absorptance + 0.7500000, !- Solar Absorptance + 0.7500000; !- Visible Absorptance + + Material, + GP01, !- Name + MediumSmooth, !- Roughness + 1.2700000E-02, !- Thickness {m} + 0.1600000, !- Conductivity {W/m-K} + 801.0000, !- Density {kg/m3} + 837.0000, !- Specific Heat {J/kg-K} + 0.9000000, !- Thermal Absorptance + 0.7500000, !- Solar Absorptance + 0.7500000; !- Visible Absorptance + + Material, + GP02, !- Name + MediumSmooth, !- Roughness + 1.5900001E-02, !- Thickness {m} + 0.1600000, !- Conductivity {W/m-K} + 801.0000, !- Density {kg/m3} + 837.0000, !- Specific Heat {J/kg-K} + 0.9000000, !- Thermal Absorptance + 0.7500000, !- Solar Absorptance + 0.7500000; !- Visible Absorptance + + Material, + CC03, !- Name + MediumRough, !- Roughness + 0.1016000, !- Thickness {m} + 1.310000, !- Conductivity {W/m-K} + 2243.000, !- Density {kg/m3} + 837.0000, !- Specific Heat {J/kg-K} + 0.9000000, !- Thermal Absorptance + 0.6500000, !- Solar Absorptance + 0.6500000; !- Visible Absorptance + + Material:NoMass, + CP01, !- Name + Rough, !- Roughness + 0.3670000, !- Thermal Resistance {m2-K/W} + 0.9000000, !- Thermal Absorptance + 0.7500000, !- Solar Absorptance + 0.7500000; !- Visible Absorptance + + Material:NoMass, + MAT-CLNG-1, !- Name + Rough, !- Roughness + 0.652259290, !- Thermal Resistance {m2-K/W} + 0.65, !- Thermal Absorptance + 0.65, !- Solar Absorptance + 0.65; !- Visible Absorptance + + Material:AirGap, + AL21, !- Name + 0.1570000; !- Thermal Resistance {m2-K/W} + + Material:AirGap, + AL23, !- Name + 0.1530000; !- Thermal Resistance {m2-K/W} + + Construction, + ROOF-1, !- Name + RG01, !- Outside Layer + BR01, !- Layer 2 + IN46, !- Layer 3 + WD01; !- Layer 4 + + Construction, + WALL-1, !- Name + WD01, !- Outside Layer + PW03, !- Layer 2 + IN02, !- Layer 3 + GP01; !- Layer 4 + + Construction, + CLNG-1, !- Name + MAT-CLNG-1; !- Outside Layer + + Construction, + FLOOR-SLAB-1, !- Name + CC03; !- Outside Layer + + Construction, + INT-WALL-1, !- Name + GP02, !- Outside Layer + AL21, !- Layer 2 + GP02; !- Layer 3 + + WindowMaterial:Gas, + AIR 13MM, !- Name + Air, !- Gas Type + 0.0127; !- Thickness {m} + + WindowMaterial:Glazing, + CLEAR 3MM, !- Name + SpectralAverage, !- Optical Data Type + , !- Window Glass Spectral Data Set Name + 0.003, !- Thickness {m} + 0.837, !- Solar Transmittance at Normal Incidence + 0.075, !- Front Side Solar Reflectance at Normal Incidence + 0.075, !- Back Side Solar Reflectance at Normal Incidence + 0.898, !- Visible Transmittance at Normal Incidence + 0.081, !- Front Side Visible Reflectance at Normal Incidence + 0.081, !- Back Side Visible Reflectance at Normal Incidence + 0.0, !- Infrared Transmittance at Normal Incidence + 0.84, !- Front Side Infrared Hemispherical Emissivity + 0.84, !- Back Side Infrared Hemispherical Emissivity + 0.9; !- Conductivity {W/m-K} + + WindowMaterial:Glazing, + GREY 3MM, !- Name + SpectralAverage, !- Optical Data Type + , !- Window Glass Spectral Data Set Name + 0.003, !- Thickness {m} + 0.626, !- Solar Transmittance at Normal Incidence + 0.061, !- Front Side Solar Reflectance at Normal Incidence + 0.061, !- Back Side Solar Reflectance at Normal Incidence + 0.611, !- Visible Transmittance at Normal Incidence + 0.061, !- Front Side Visible Reflectance at Normal Incidence + 0.061, !- Back Side Visible Reflectance at Normal Incidence + 0.0, !- Infrared Transmittance at Normal Incidence + 0.84, !- Front Side Infrared Hemispherical Emissivity + 0.84, !- Back Side Infrared Hemispherical Emissivity + 0.9; !- Conductivity {W/m-K} + + Construction, + Dbl Clr 3mm/13mm Air, !- Name + CLEAR 3MM, !- Outside Layer + AIR 13MM, !- Layer 2 + CLEAR 3MM; !- Layer 3 + + Construction, + Sgl Grey 3mm, !- Name + GREY 3MM; !- Outside Layer + + Schedule:Compact, + OCCUPY-1, !- Name + Fraction, !- Schedule Type Limits Name + Through: 12/31, !- Field 1 + For: WeekDays SummerDesignDay CustomDay1 CustomDay2, !- Field 2 + Until: 8:00,0.0, !- Field 3 + Until: 11:00,1.00, !- Field 5 + Until: 12:00,0.80, !- Field 7 + Until: 13:00,0.40, !- Field 9 + Until: 14:00,0.80, !- Field 11 + Until: 18:00,1.00, !- Field 13 + Until: 19:00,0.50, !- Field 15 + Until: 24:00,0.0, !- Field 17 + For: Weekends WinterDesignDay Holiday, !- Field 19 + Until: 24:00,0.0; !- Field 20 + + Schedule:Compact, + LIGHTS-1, !- Name + Fraction, !- Schedule Type Limits Name + Through: 12/31, !- Field 1 + For: WeekDays SummerDesignDay CustomDay1 CustomDay2, !- Field 2 + Until: 8:00,0.05, !- Field 3 + Until: 9:00,0.9, !- Field 5 + Until: 10:00,0.95, !- Field 7 + Until: 11:00,1.00, !- Field 9 + Until: 12:00,0.95, !- Field 11 + Until: 13:00,0.8, !- Field 13 + Until: 14:00,0.9, !- Field 15 + Until: 18:00,1.00, !- Field 17 + Until: 19:00,0.60, !- Field 19 + Until: 21:00,0.20, !- Field 21 + Until: 24:00,0.05, !- Field 23 + For: Weekends WinterDesignDay Holiday, !- Field 25 + Until: 24:00,0.05; !- Field 26 + + Schedule:Compact, + EQUIP-1, !- Name + Fraction, !- Schedule Type Limits Name + Through: 12/31, !- Field 1 + For: WeekDays SummerDesignDay CustomDay1 CustomDay2, !- Field 2 + Until: 8:00,0.02, !- Field 3 + Until: 9:00,0.4, !- Field 5 + Until: 14:00,0.9, !- Field 7 + Until: 15:00,0.8, !- Field 9 + Until: 16:00,0.7, !- Field 11 + Until: 18:00,0.5, !- Field 13 + Until: 20:00,0.3, !- Field 15 + Until: 24:00,0.02, !- Field 17 + For: Weekends WinterDesignDay Holiday, !- Field 19 + Until: 24:00,0.2; !- Field 20 + + Schedule:Compact, + INFIL-SCH, !- Name + Fraction, !- Schedule Type Limits Name + Through: 3/31, !- Field 1 + For: AllDays, !- Field 2 + Until: 24:00,1.0, !- Field 3 + Through: 10/31, !- Field 5 + For: AllDays, !- Field 6 + Until: 24:00,0.0, !- Field 7 + Through: 12/31, !- Field 9 + For: AllDays, !- Field 10 + Until: 24:00,1.0; !- Field 11 + + Schedule:Compact, + ActSchd, !- Name + Any Number, !- Schedule Type Limits Name + Through: 12/31, !- Field 1 + For: AllDays, !- Field 2 + Until: 24:00,117.239997864; !- Field 3 + + !- Field 4 + + Schedule:Compact, + ShadeTransSch, !- Name + Fraction, !- Schedule Type Limits Name + Through: 12/31, !- Field 1 + For: AllDays, !- Field 2 + Until: 24:00,0.0; !- Field 3 + + Zone, + PLENUM-1, !- Name + 0, !- Direction of Relative North {deg} + 0, !- X Origin {m} + 0, !- Y Origin {m} + 0, !- Z Origin {m} + 1, !- Type + 1, !- Multiplier + 0.609600067, !- Ceiling Height {m} + 283.2; !- Volume {m3} + + BuildingSurface:Detailed, + WALL-1PF, !- Name + WALL, !- Surface Type + WALL-1, !- Construction Name + PLENUM-1, !- Zone Name + , !- Space Name + Outdoors, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + SunExposed, !- Sun Exposure + WindExposed, !- Wind Exposure + 0.50000, !- View Factor to Ground + 4, !- Number of Vertices + 0.0,0.0,3.0, !- X,Y,Z ==> Vertex 1 {m} + 0.0,0.0,2.4, !- X,Y,Z ==> Vertex 2 {m} + 30.5,0.0,2.4, !- X,Y,Z ==> Vertex 3 {m} + 30.5,0.0,3.0; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + WALL-1PR, !- Name + WALL, !- Surface Type + WALL-1, !- Construction Name + PLENUM-1, !- Zone Name + , !- Space Name + Outdoors, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + SunExposed, !- Sun Exposure + WindExposed, !- Wind Exposure + 0.50000, !- View Factor to Ground + 4, !- Number of Vertices + 30.5,0.0,3.0, !- X,Y,Z ==> Vertex 1 {m} + 30.5,0.0,2.4, !- X,Y,Z ==> Vertex 2 {m} + 30.5,15.2,2.4, !- X,Y,Z ==> Vertex 3 {m} + 30.5,15.2,3.0; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + WALL-1PB, !- Name + WALL, !- Surface Type + WALL-1, !- Construction Name + PLENUM-1, !- Zone Name + , !- Space Name + Outdoors, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + SunExposed, !- Sun Exposure + WindExposed, !- Wind Exposure + 0.50000, !- View Factor to Ground + 4, !- Number of Vertices + 30.5,15.2,3.0, !- X,Y,Z ==> Vertex 1 {m} + 30.5,15.2,2.4, !- X,Y,Z ==> Vertex 2 {m} + 0.0,15.2,2.4, !- X,Y,Z ==> Vertex 3 {m} + 0.0,15.2,3.0; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + WALL-1PL, !- Name + WALL, !- Surface Type + WALL-1, !- Construction Name + PLENUM-1, !- Zone Name + , !- Space Name + Outdoors, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + SunExposed, !- Sun Exposure + WindExposed, !- Wind Exposure + 0.50000, !- View Factor to Ground + 4, !- Number of Vertices + 0.0,15.2,3.0, !- X,Y,Z ==> Vertex 1 {m} + 0.0,15.2,2.4, !- X,Y,Z ==> Vertex 2 {m} + 0.0,0.0,2.4, !- X,Y,Z ==> Vertex 3 {m} + 0.0,0.0,3.0; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + TOP-1, !- Name + ROOF, !- Surface Type + ROOF-1, !- Construction Name + PLENUM-1, !- Zone Name + , !- Space Name + Outdoors, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + SunExposed, !- Sun Exposure + WindExposed, !- Wind Exposure + 0.00000, !- View Factor to Ground + 4, !- Number of Vertices + 0.0,15.2,3.0, !- X,Y,Z ==> Vertex 1 {m} + 0.0,0.0,3.0, !- X,Y,Z ==> Vertex 2 {m} + 30.5,0.0,3.0, !- X,Y,Z ==> Vertex 3 {m} + 30.5,15.2,3.0; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + C1-1P, !- Name + FLOOR, !- Surface Type + CLNG-1, !- Construction Name + PLENUM-1, !- Zone Name + , !- Space Name + Surface, !- Outside Boundary Condition + C1-1, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 26.8,3.7,2.4, !- X,Y,Z ==> Vertex 1 {m} + 30.5,0.0,2.4, !- X,Y,Z ==> Vertex 2 {m} + 0.0,0.0,2.4, !- X,Y,Z ==> Vertex 3 {m} + 3.7,3.7,2.4; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + C2-1P, !- Name + FLOOR, !- Surface Type + CLNG-1, !- Construction Name + PLENUM-1, !- Zone Name + , !- Space Name + Surface, !- Outside Boundary Condition + C2-1, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 26.8,11.6,2.4, !- X,Y,Z ==> Vertex 1 {m} + 30.5,15.2,2.4, !- X,Y,Z ==> Vertex 2 {m} + 30.5,0.0,2.4, !- X,Y,Z ==> Vertex 3 {m} + 26.8,3.7,2.4; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + C3-1P, !- Name + FLOOR, !- Surface Type + CLNG-1, !- Construction Name + PLENUM-1, !- Zone Name + , !- Space Name + Surface, !- Outside Boundary Condition + C3-1, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 26.8,11.6,2.4, !- X,Y,Z ==> Vertex 1 {m} + 3.7,11.6,2.4, !- X,Y,Z ==> Vertex 2 {m} + 0.0,15.2,2.4, !- X,Y,Z ==> Vertex 3 {m} + 30.5,15.2,2.4; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + C4-1P, !- Name + FLOOR, !- Surface Type + CLNG-1, !- Construction Name + PLENUM-1, !- Zone Name + , !- Space Name + Surface, !- Outside Boundary Condition + C4-1, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 3.7,3.7,2.4, !- X,Y,Z ==> Vertex 1 {m} + 0.0,0.0,2.4, !- X,Y,Z ==> Vertex 2 {m} + 0.0,15.2,2.4, !- X,Y,Z ==> Vertex 3 {m} + 3.7,11.6,2.4; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + C5-1P, !- Name + FLOOR, !- Surface Type + CLNG-1, !- Construction Name + PLENUM-1, !- Zone Name + , !- Space Name + Surface, !- Outside Boundary Condition + C5-1, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 26.8,11.6,2.4, !- X,Y,Z ==> Vertex 1 {m} + 26.8,3.7,2.4, !- X,Y,Z ==> Vertex 2 {m} + 3.7,3.7,2.4, !- X,Y,Z ==> Vertex 3 {m} + 3.7,11.6,2.4; !- X,Y,Z ==> Vertex 4 {m} + + Zone, + SPACE1-1, !- Name + 0, !- Direction of Relative North {deg} + 0, !- X Origin {m} + 0, !- Y Origin {m} + 0, !- Z Origin {m} + 1, !- Type + 1, !- Multiplier + 2.438400269, !- Ceiling Height {m} + 239.247360229; !- Volume {m3} + + ZoneInfiltration:DesignFlowRate, + SPACE1-1 Infil 1, !- Name + SPACE1-1, !- Zone or ZoneList or Space or SpaceList Name + INFIL-SCH, !- Schedule Name + flow/zone, !- Design Flow Rate Calculation Method + 0.032, !- Design Flow Rate {m3/s} + , !- Flow per Zone Floor Area {m3/s-m2} + , !- Flow per Exterior Surface Area {m3/s-m2} + , !- Air Changes per Hour {1/hr} + 0, !- Constant Term Coefficient + 0, !- Temperature Term Coefficient + 0.2237, !- Velocity Term Coefficient + 0; !- Velocity Squared Term Coefficient + + People, + SPACE1-1 People 1, !- Name + SPACE1-1, !- Zone or ZoneList or Space or SpaceList Name + OCCUPY-1, !- Number of People Schedule Name + people, !- Number of People Calculation Method + 11, !- Number of People + , !- People per Floor Area {person/m2} + , !- Floor Area per Person {m2/person} + 0.3, !- Fraction Radiant + , !- Sensible Heat Fraction + ActSchd; !- Activity Level Schedule Name + + Lights, + SPACE1-1 Lights 1, !- Name + SPACE1-1, !- Zone or ZoneList or Space or SpaceList Name + LIGHTS-1, !- Schedule Name + LightingLevel, !- Design Level Calculation Method + 1584, !- Lighting Level {W} + , !- Watts per Zone Floor Area {W/m2} + , !- Watts per Person {W/person} + 0.2, !- Return Air Fraction + 0.59, !- Fraction Radiant + 0.2, !- Fraction Visible + 0, !- Fraction Replaceable + GeneralLights; !- End-Use Subcategory + + ElectricEquipment, + SPACE1-1 ElecEq 1, !- Name + SPACE1-1, !- Zone or ZoneList or Space or SpaceList Name + EQUIP-1, !- Schedule Name + EquipmentLevel, !- Design Level Calculation Method + 1056, !- Design Level {W} + , !- Watts per Zone Floor Area {W/m2} + , !- Watts per Person {W/person} + 0, !- Fraction Latent + 0.3, !- Fraction Radiant + 0; !- Fraction Lost + + BuildingSurface:Detailed, + FRONT-1, !- Name + WALL, !- Surface Type + WALL-1, !- Construction Name + SPACE1-1, !- Zone Name + , !- Space Name + Outdoors, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + SunExposed, !- Sun Exposure + WindExposed, !- Wind Exposure + 0.50000, !- View Factor to Ground + 4, !- Number of Vertices + 0.0,0.0,2.4, !- X,Y,Z ==> Vertex 1 {m} + 0.0,0.0,0.0, !- X,Y,Z ==> Vertex 2 {m} + 30.5,0.0,0.0, !- X,Y,Z ==> Vertex 3 {m} + 30.5,0.0,2.4; !- X,Y,Z ==> Vertex 4 {m} + + FenestrationSurface:Detailed, + WF-1, !- Name + WINDOW, !- Surface Type + Dbl Clr 3mm/13mm Air, !- Construction Name + FRONT-1, !- Building Surface Name + , !- Outside Boundary Condition Object + 0.50000, !- View Factor to Ground + , !- Frame and Divider Name + 1, !- Multiplier + 4, !- Number of Vertices + 3.0,0.0,2.1, !- X,Y,Z ==> Vertex 1 {m} + 3.0,0.0,0.9, !- X,Y,Z ==> Vertex 2 {m} + 16.8,0.0,0.9, !- X,Y,Z ==> Vertex 3 {m} + 16.8,0.0,2.1; !- X,Y,Z ==> Vertex 4 {m} + + FenestrationSurface:Detailed, + DF-1, !- Name + GLASSDOOR, !- Surface Type + Sgl Grey 3mm, !- Construction Name + FRONT-1, !- Building Surface Name + , !- Outside Boundary Condition Object + 0.50000, !- View Factor to Ground + , !- Frame and Divider Name + 1, !- Multiplier + 4, !- Number of Vertices + 21.3,0.0,2.1, !- X,Y,Z ==> Vertex 1 {m} + 21.3,0.0,0.0, !- X,Y,Z ==> Vertex 2 {m} + 23.8,0.0,0.0, !- X,Y,Z ==> Vertex 3 {m} + 23.8,0.0,2.1; !- X,Y,Z ==> Vertex 4 {m} + + Shading:Zone:Detailed, + Main South Overhang, !- Name + FRONT-1, !- Base Surface Name + ShadeTransSch, !- Transmittance Schedule Name + 4, !- Number of Vertices + 0.0,-1.3,2.2, !- X,Y,Z ==> Vertex 1 {m} + 0.0,0.0,2.2, !- X,Y,Z ==> Vertex 2 {m} + 19.8,0.0,2.2, !- X,Y,Z ==> Vertex 3 {m} + 19.8,-1.3,2.2; !- X,Y,Z ==> Vertex 4 {m} + + Shading:Zone:Detailed, + South Door Overhang, !- Name + FRONT-1, !- Base Surface Name + ShadeTransSch, !- Transmittance Schedule Name + 4, !- Number of Vertices + 21.0,-2.0,2.6, !- X,Y,Z ==> Vertex 1 {m} + 21.0,0.0,2.6, !- X,Y,Z ==> Vertex 2 {m} + 24.1,0.0,2.6, !- X,Y,Z ==> Vertex 3 {m} + 24.1,-2.0,2.6; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + C1-1, !- Name + CEILING, !- Surface Type + CLNG-1, !- Construction Name + SPACE1-1, !- Zone Name + , !- Space Name + Surface, !- Outside Boundary Condition + C1-1P, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 3.7,3.7,2.4, !- X,Y,Z ==> Vertex 1 {m} + 0.0,0.0,2.4, !- X,Y,Z ==> Vertex 2 {m} + 30.5,0.0,2.4, !- X,Y,Z ==> Vertex 3 {m} + 26.8,3.7,2.4; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + F1-1, !- Name + FLOOR, !- Surface Type + FLOOR-SLAB-1, !- Construction Name + SPACE1-1, !- Zone Name + , !- Space Name + Ground, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 26.8,3.7,0.0, !- X,Y,Z ==> Vertex 1 {m} + 30.5,0.0,0.0, !- X,Y,Z ==> Vertex 2 {m} + 0.0,0.0,0.0, !- X,Y,Z ==> Vertex 3 {m} + 3.7,3.7,0.0; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + SB12, !- Name + WALL, !- Surface Type + INT-WALL-1, !- Construction Name + SPACE1-1, !- Zone Name + , !- Space Name + Surface, !- Outside Boundary Condition + SB21, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 30.5,0.0,2.4, !- X,Y,Z ==> Vertex 1 {m} + 30.5,0.0,0.0, !- X,Y,Z ==> Vertex 2 {m} + 26.8,3.7,0.0, !- X,Y,Z ==> Vertex 3 {m} + 26.8,3.7,2.4; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + SB14, !- Name + WALL, !- Surface Type + INT-WALL-1, !- Construction Name + SPACE1-1, !- Zone Name + , !- Space Name + Surface, !- Outside Boundary Condition + SB41, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 3.7,3.7,2.4, !- X,Y,Z ==> Vertex 1 {m} + 3.7,3.7,0.0, !- X,Y,Z ==> Vertex 2 {m} + 0.0,0.0,0.0, !- X,Y,Z ==> Vertex 3 {m} + 0.0,0.0,2.4; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + SB15, !- Name + WALL, !- Surface Type + INT-WALL-1, !- Construction Name + SPACE1-1, !- Zone Name + , !- Space Name + Surface, !- Outside Boundary Condition + SB51, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 26.8,3.7,2.4, !- X,Y,Z ==> Vertex 1 {m} + 26.8,3.7,0.0, !- X,Y,Z ==> Vertex 2 {m} + 3.7,3.7,0.0, !- X,Y,Z ==> Vertex 3 {m} + 3.7,3.7,2.4; !- X,Y,Z ==> Vertex 4 {m} + + Zone, + SPACE2-1, !- Name + 0, !- Direction of Relative North {deg} + 0, !- X Origin {m} + 0, !- Y Origin {m} + 0, !- Z Origin {m} + 1, !- Type + 1, !- Multiplier + 2.438400269, !- Ceiling Height {m} + 103.311355591; !- Volume {m3} + + ZoneInfiltration:DesignFlowRate, + SPACE2-1 Infil 1, !- Name + SPACE2-1, !- Zone or ZoneList or Space or SpaceList Name + INFIL-SCH, !- Schedule Name + flow/zone, !- Design Flow Rate Calculation Method + 0.014, !- Design Flow Rate {m3/s} + , !- Flow per Zone Floor Area {m3/s-m2} + , !- Flow per Exterior Surface Area {m3/s-m2} + , !- Air Changes per Hour {1/hr} + 0, !- Constant Term Coefficient + 0, !- Temperature Term Coefficient + 0.2237, !- Velocity Term Coefficient + 0; !- Velocity Squared Term Coefficient + + People, + SPACE2-1 People 1, !- Name + SPACE2-1, !- Zone or ZoneList or Space or SpaceList Name + OCCUPY-1, !- Number of People Schedule Name + people, !- Number of People Calculation Method + 5, !- Number of People + , !- People per Floor Area {person/m2} + , !- Floor Area per Person {m2/person} + 0.3, !- Fraction Radiant + , !- Sensible Heat Fraction + ActSchd; !- Activity Level Schedule Name + + Lights, + SPACE2-1 Lights 1, !- Name + SPACE2-1, !- Zone or ZoneList or Space or SpaceList Name + LIGHTS-1, !- Schedule Name + LightingLevel, !- Design Level Calculation Method + 684, !- Lighting Level {W} + , !- Watts per Zone Floor Area {W/m2} + , !- Watts per Person {W/person} + 0.2, !- Return Air Fraction + 0.59, !- Fraction Radiant + 0.2, !- Fraction Visible + 0, !- Fraction Replaceable + GeneralLights; !- End-Use Subcategory + + ElectricEquipment, + SPACE2-1 ElecEq 1, !- Name + SPACE2-1, !- Zone or ZoneList or Space or SpaceList Name + EQUIP-1, !- Schedule Name + EquipmentLevel, !- Design Level Calculation Method + 456, !- Design Level {W} + , !- Watts per Zone Floor Area {W/m2} + , !- Watts per Person {W/person} + 0, !- Fraction Latent + 0.3, !- Fraction Radiant + 0; !- Fraction Lost + + BuildingSurface:Detailed, + RIGHT-1, !- Name + WALL, !- Surface Type + WALL-1, !- Construction Name + SPACE2-1, !- Zone Name + , !- Space Name + Outdoors, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + SunExposed, !- Sun Exposure + WindExposed, !- Wind Exposure + 0.50000, !- View Factor to Ground + 4, !- Number of Vertices + 30.5,0.0,2.4, !- X,Y,Z ==> Vertex 1 {m} + 30.5,0.0,0.0, !- X,Y,Z ==> Vertex 2 {m} + 30.5,15.2,0.0, !- X,Y,Z ==> Vertex 3 {m} + 30.5,15.2,2.4; !- X,Y,Z ==> Vertex 4 {m} + + FenestrationSurface:Detailed, + WR-1, !- Name + WINDOW, !- Surface Type + Dbl Clr 3mm/13mm Air, !- Construction Name + RIGHT-1, !- Building Surface Name + , !- Outside Boundary Condition Object + 0.50000, !- View Factor to Ground + , !- Frame and Divider Name + 1, !- Multiplier + 4, !- Number of Vertices + 30.5,3.8,2.1, !- X,Y,Z ==> Vertex 1 {m} + 30.5,3.8,0.9, !- X,Y,Z ==> Vertex 2 {m} + 30.5,11.4,0.9, !- X,Y,Z ==> Vertex 3 {m} + 30.5,11.4,2.1; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + C2-1, !- Name + CEILING, !- Surface Type + CLNG-1, !- Construction Name + SPACE2-1, !- Zone Name + , !- Space Name + Surface, !- Outside Boundary Condition + C2-1P, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 26.8,3.7,2.4, !- X,Y,Z ==> Vertex 1 {m} + 30.5,0.0,2.4, !- X,Y,Z ==> Vertex 2 {m} + 30.5,15.2,2.4, !- X,Y,Z ==> Vertex 3 {m} + 26.8,11.6,2.4; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + F2-1, !- Name + FLOOR, !- Surface Type + FLOOR-SLAB-1, !- Construction Name + SPACE2-1, !- Zone Name + , !- Space Name + Ground, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 26.8,11.6,0.0, !- X,Y,Z ==> Vertex 1 {m} + 30.5,15.2,0.0, !- X,Y,Z ==> Vertex 2 {m} + 30.5,0.0,0.0, !- X,Y,Z ==> Vertex 3 {m} + 26.8,3.7,0.0; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + SB21, !- Name + WALL, !- Surface Type + INT-WALL-1, !- Construction Name + SPACE2-1, !- Zone Name + , !- Space Name + Surface, !- Outside Boundary Condition + SB12, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 26.8,3.7,2.4, !- X,Y,Z ==> Vertex 1 {m} + 26.8,3.7,0.0, !- X,Y,Z ==> Vertex 2 {m} + 30.5,0.0,0.0, !- X,Y,Z ==> Vertex 3 {m} + 30.5,0.0,2.4; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + SB23, !- Name + WALL, !- Surface Type + INT-WALL-1, !- Construction Name + SPACE2-1, !- Zone Name + , !- Space Name + Surface, !- Outside Boundary Condition + SB32, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 30.5,15.2,2.4, !- X,Y,Z ==> Vertex 1 {m} + 30.5,15.2,0.0, !- X,Y,Z ==> Vertex 2 {m} + 26.8,11.6,0.0, !- X,Y,Z ==> Vertex 3 {m} + 26.8,11.6,2.4; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + SB25, !- Name + WALL, !- Surface Type + INT-WALL-1, !- Construction Name + SPACE2-1, !- Zone Name + , !- Space Name + Surface, !- Outside Boundary Condition + SB52, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 26.8,11.6,2.4, !- X,Y,Z ==> Vertex 1 {m} + 26.8,11.6,0.0, !- X,Y,Z ==> Vertex 2 {m} + 26.8,3.7,0.0, !- X,Y,Z ==> Vertex 3 {m} + 26.8,3.7,2.4; !- X,Y,Z ==> Vertex 4 {m} + + Zone, + SPACE3-1, !- Name + 0, !- Direction of Relative North {deg} + 0, !- X Origin {m} + 0, !- Y Origin {m} + 0, !- Z Origin {m} + 1, !- Type + 1, !- Multiplier + 2.438400269, !- Ceiling Height {m} + 239.247360229; !- Volume {m3} + + ZoneInfiltration:DesignFlowRate, + SPACE3-1 Infil 1, !- Name + SPACE3-1, !- Zone or ZoneList or Space or SpaceList Name + INFIL-SCH, !- Schedule Name + flow/zone, !- Design Flow Rate Calculation Method + 0.032, !- Design Flow Rate {m3/s} + , !- Flow per Zone Floor Area {m3/s-m2} + , !- Flow per Exterior Surface Area {m3/s-m2} + , !- Air Changes per Hour {1/hr} + 0, !- Constant Term Coefficient + 0, !- Temperature Term Coefficient + 0.2237, !- Velocity Term Coefficient + 0; !- Velocity Squared Term Coefficient + + People, + SPACE3-1 People 1, !- Name + SPACE3-1, !- Zone or ZoneList or Space or SpaceList Name + OCCUPY-1, !- Number of People Schedule Name + people, !- Number of People Calculation Method + 11, !- Number of People + , !- People per Floor Area {person/m2} + , !- Floor Area per Person {m2/person} + 0.3, !- Fraction Radiant + , !- Sensible Heat Fraction + ActSchd; !- Activity Level Schedule Name + + Lights, + SPACE3-1 Lights 1, !- Name + SPACE3-1, !- Zone or ZoneList or Space or SpaceList Name + LIGHTS-1, !- Schedule Name + LightingLevel, !- Design Level Calculation Method + 1584, !- Lighting Level {W} + , !- Watts per Zone Floor Area {W/m2} + , !- Watts per Person {W/person} + 0.2, !- Return Air Fraction + 0.59, !- Fraction Radiant + 0.2, !- Fraction Visible + 0, !- Fraction Replaceable + GeneralLights; !- End-Use Subcategory + + ElectricEquipment, + SPACE3-1 ElecEq 1, !- Name + SPACE3-1, !- Zone or ZoneList or Space or SpaceList Name + EQUIP-1, !- Schedule Name + EquipmentLevel, !- Design Level Calculation Method + 1056, !- Design Level {W} + , !- Watts per Zone Floor Area {W/m2} + , !- Watts per Person {W/person} + 0, !- Fraction Latent + 0.3, !- Fraction Radiant + 0; !- Fraction Lost + + BuildingSurface:Detailed, + BACK-1, !- Name + WALL, !- Surface Type + WALL-1, !- Construction Name + SPACE3-1, !- Zone Name + , !- Space Name + Outdoors, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + SunExposed, !- Sun Exposure + WindExposed, !- Wind Exposure + 0.50000, !- View Factor to Ground + 4, !- Number of Vertices + 30.5,15.2,2.4, !- X,Y,Z ==> Vertex 1 {m} + 30.5,15.2,0.0, !- X,Y,Z ==> Vertex 2 {m} + 0.0,15.2,0.0, !- X,Y,Z ==> Vertex 3 {m} + 0.0,15.2,2.4; !- X,Y,Z ==> Vertex 4 {m} + + FenestrationSurface:Detailed, + WB-1, !- Name + WINDOW, !- Surface Type + Dbl Clr 3mm/13mm Air, !- Construction Name + BACK-1, !- Building Surface Name + , !- Outside Boundary Condition Object + 0.50000, !- View Factor to Ground + , !- Frame and Divider Name + 1, !- Multiplier + 4, !- Number of Vertices + 27.4,15.2,2.1, !- X,Y,Z ==> Vertex 1 {m} + 27.4,15.2,0.9, !- X,Y,Z ==> Vertex 2 {m} + 13.7,15.2,0.9, !- X,Y,Z ==> Vertex 3 {m} + 13.7,15.2,2.1; !- X,Y,Z ==> Vertex 4 {m} + + FenestrationSurface:Detailed, + DB-1, !- Name + GLASSDOOR, !- Surface Type + Sgl Grey 3mm, !- Construction Name + BACK-1, !- Building Surface Name + , !- Outside Boundary Condition Object + 0.50000, !- View Factor to Ground + , !- Frame and Divider Name + 1, !- Multiplier + 4, !- Number of Vertices + 9.1,15.2,2.1, !- X,Y,Z ==> Vertex 1 {m} + 9.1,15.2,0.0, !- X,Y,Z ==> Vertex 2 {m} + 7.0,15.2,0.0, !- X,Y,Z ==> Vertex 3 {m} + 7.0,15.2,2.1; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + C3-1, !- Name + CEILING, !- Surface Type + CLNG-1, !- Construction Name + SPACE3-1, !- Zone Name + , !- Space Name + Surface, !- Outside Boundary Condition + C3-1P, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 30.5,15.2,2.4, !- X,Y,Z ==> Vertex 1 {m} + 0.0,15.2,2.4, !- X,Y,Z ==> Vertex 2 {m} + 3.7,11.6,2.4, !- X,Y,Z ==> Vertex 3 {m} + 26.8,11.6,2.4; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + F3-1, !- Name + FLOOR, !- Surface Type + FLOOR-SLAB-1, !- Construction Name + SPACE3-1, !- Zone Name + , !- Space Name + Ground, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 26.8,11.6,0.0, !- X,Y,Z ==> Vertex 1 {m} + 3.7,11.6,0.0, !- X,Y,Z ==> Vertex 2 {m} + 0.0,15.2,0.0, !- X,Y,Z ==> Vertex 3 {m} + 30.5,15.2,0.0; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + SB32, !- Name + WALL, !- Surface Type + INT-WALL-1, !- Construction Name + SPACE3-1, !- Zone Name + , !- Space Name + Surface, !- Outside Boundary Condition + SB23, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 26.8,11.6,2.4, !- X,Y,Z ==> Vertex 1 {m} + 26.8,11.6,0.0, !- X,Y,Z ==> Vertex 2 {m} + 30.5,15.2,0.0, !- X,Y,Z ==> Vertex 3 {m} + 30.5,15.2,2.4; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + SB34, !- Name + WALL, !- Surface Type + INT-WALL-1, !- Construction Name + SPACE3-1, !- Zone Name + , !- Space Name + Surface, !- Outside Boundary Condition + SB43, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 0.0,15.2,2.4, !- X,Y,Z ==> Vertex 1 {m} + 0.0,15.2,0.0, !- X,Y,Z ==> Vertex 2 {m} + 3.7,11.6,0.0, !- X,Y,Z ==> Vertex 3 {m} + 3.7,11.6,2.4; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + SB35, !- Name + WALL, !- Surface Type + INT-WALL-1, !- Construction Name + SPACE3-1, !- Zone Name + , !- Space Name + Surface, !- Outside Boundary Condition + SB53, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 3.7,11.6,2.4, !- X,Y,Z ==> Vertex 1 {m} + 3.7,11.6,0.0, !- X,Y,Z ==> Vertex 2 {m} + 26.8,11.6,0.0, !- X,Y,Z ==> Vertex 3 {m} + 26.8,11.6,2.4; !- X,Y,Z ==> Vertex 4 {m} + + Zone, + SPACE4-1, !- Name + 0, !- Direction of Relative North {deg} + 0, !- X Origin {m} + 0, !- Y Origin {m} + 0, !- Z Origin {m} + 1, !- Type + 1, !- Multiplier + 2.438400269, !- Ceiling Height {m} + 103.311355591; !- Volume {m3} + + ZoneInfiltration:DesignFlowRate, + SPACE4-1 Infil 1, !- Name + SPACE4-1, !- Zone or ZoneList or Space or SpaceList Name + INFIL-SCH, !- Schedule Name + flow/zone, !- Design Flow Rate Calculation Method + 0.014, !- Design Flow Rate {m3/s} + , !- Flow per Zone Floor Area {m3/s-m2} + , !- Flow per Exterior Surface Area {m3/s-m2} + , !- Air Changes per Hour {1/hr} + 0, !- Constant Term Coefficient + 0, !- Temperature Term Coefficient + 0.2237, !- Velocity Term Coefficient + 0; !- Velocity Squared Term Coefficient + + People, + SPACE4-1 People 1, !- Name + SPACE4-1, !- Zone or ZoneList or Space or SpaceList Name + OCCUPY-1, !- Number of People Schedule Name + people, !- Number of People Calculation Method + 5, !- Number of People + , !- People per Floor Area {person/m2} + , !- Floor Area per Person {m2/person} + 0.3, !- Fraction Radiant + , !- Sensible Heat Fraction + ActSchd; !- Activity Level Schedule Name + + Lights, + SPACE4-1 Lights 1, !- Name + SPACE4-1, !- Zone or ZoneList or Space or SpaceList Name + LIGHTS-1, !- Schedule Name + LightingLevel, !- Design Level Calculation Method + 684, !- Lighting Level {W} + , !- Watts per Zone Floor Area {W/m2} + , !- Watts per Person {W/person} + 0.2, !- Return Air Fraction + 0.59, !- Fraction Radiant + 0.2, !- Fraction Visible + 0, !- Fraction Replaceable + GeneralLights; !- End-Use Subcategory + + ElectricEquipment, + SPACE4-1 ElecEq 1, !- Name + SPACE4-1, !- Zone or ZoneList or Space or SpaceList Name + EQUIP-1, !- Schedule Name + EquipmentLevel, !- Design Level Calculation Method + 456, !- Design Level {W} + , !- Watts per Zone Floor Area {W/m2} + , !- Watts per Person {W/person} + 0, !- Fraction Latent + 0.3, !- Fraction Radiant + 0; !- Fraction Lost + + BuildingSurface:Detailed, + LEFT-1, !- Name + WALL, !- Surface Type + WALL-1, !- Construction Name + SPACE4-1, !- Zone Name + , !- Space Name + Outdoors, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + SunExposed, !- Sun Exposure + WindExposed, !- Wind Exposure + 0.50000, !- View Factor to Ground + 4, !- Number of Vertices + 0.0,15.2,2.4, !- X,Y,Z ==> Vertex 1 {m} + 0.0,15.2,0.0, !- X,Y,Z ==> Vertex 2 {m} + 0.0,0.0,0.0, !- X,Y,Z ==> Vertex 3 {m} + 0.0,0.0,2.4; !- X,Y,Z ==> Vertex 4 {m} + + FenestrationSurface:Detailed, + WL-1, !- Name + WINDOW, !- Surface Type + Dbl Clr 3mm/13mm Air, !- Construction Name + LEFT-1, !- Building Surface Name + , !- Outside Boundary Condition Object + 0.50000, !- View Factor to Ground + , !- Frame and Divider Name + 1, !- Multiplier + 4, !- Number of Vertices + 0.0,11.4,2.1, !- X,Y,Z ==> Vertex 1 {m} + 0.0,11.4,0.9, !- X,Y,Z ==> Vertex 2 {m} + 0.0,3.8,0.9, !- X,Y,Z ==> Vertex 3 {m} + 0.0,3.8,2.1; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + C4-1, !- Name + CEILING, !- Surface Type + CLNG-1, !- Construction Name + SPACE4-1, !- Zone Name + , !- Space Name + Surface, !- Outside Boundary Condition + C4-1P, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 3.7,11.6,2.4, !- X,Y,Z ==> Vertex 1 {m} + 0.0,15.2,2.4, !- X,Y,Z ==> Vertex 2 {m} + 0.0,0.0,2.4, !- X,Y,Z ==> Vertex 3 {m} + 3.7,3.7,2.4; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + F4-1, !- Name + FLOOR, !- Surface Type + FLOOR-SLAB-1, !- Construction Name + SPACE4-1, !- Zone Name + , !- Space Name + Ground, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 3.7,3.7,0.0, !- X,Y,Z ==> Vertex 1 {m} + 0.0,0.0,0.0, !- X,Y,Z ==> Vertex 2 {m} + 0.0,15.2,0.0, !- X,Y,Z ==> Vertex 3 {m} + 3.7,11.6,0.0; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + SB41, !- Name + WALL, !- Surface Type + INT-WALL-1, !- Construction Name + SPACE4-1, !- Zone Name + , !- Space Name + Surface, !- Outside Boundary Condition + SB14, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 0.0,0.0,2.4, !- X,Y,Z ==> Vertex 1 {m} + 0.0,0.0,0.0, !- X,Y,Z ==> Vertex 2 {m} + 3.7,3.7,0.0, !- X,Y,Z ==> Vertex 3 {m} + 3.7,3.7,2.4; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + SB43, !- Name + WALL, !- Surface Type + INT-WALL-1, !- Construction Name + SPACE4-1, !- Zone Name + , !- Space Name + Surface, !- Outside Boundary Condition + SB34, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 3.7,11.6,2.4, !- X,Y,Z ==> Vertex 1 {m} + 3.7,11.6,0.0, !- X,Y,Z ==> Vertex 2 {m} + 0.0,15.2,0.0, !- X,Y,Z ==> Vertex 3 {m} + 0.0,15.2,2.4; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + SB45, !- Name + WALL, !- Surface Type + INT-WALL-1, !- Construction Name + SPACE4-1, !- Zone Name + , !- Space Name + Surface, !- Outside Boundary Condition + SB54, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 3.7,3.7,2.4, !- X,Y,Z ==> Vertex 1 {m} + 3.7,3.7,0.0, !- X,Y,Z ==> Vertex 2 {m} + 3.7,11.6,0.0, !- X,Y,Z ==> Vertex 3 {m} + 3.7,11.6,2.4; !- X,Y,Z ==> Vertex 4 {m} + + Zone, + SPACE5-1, !- Name + 0, !- Direction of Relative North {deg} + 0, !- X Origin {m} + 0, !- Y Origin {m} + 0, !- Z Origin {m} + 1, !- Type + 1, !- Multiplier + 2.438400269, !- Ceiling Height {m} + 447.682556152; !- Volume {m3} + + ZoneInfiltration:DesignFlowRate, + SPACE5-1 Infil 1, !- Name + SPACE5-1, !- Zone or ZoneList or Space or SpaceList Name + INFIL-SCH, !- Schedule Name + flow/zone, !- Design Flow Rate Calculation Method + 0.062, !- Design Flow Rate {m3/s} + , !- Flow per Zone Floor Area {m3/s-m2} + , !- Flow per Exterior Surface Area {m3/s-m2} + , !- Air Changes per Hour {1/hr} + 0, !- Constant Term Coefficient + 0, !- Temperature Term Coefficient + 0.2237, !- Velocity Term Coefficient + 0; !- Velocity Squared Term Coefficient + + People, + SPACE5-1 People 1, !- Name + SPACE5-1, !- Zone or ZoneList or Space or SpaceList Name + OCCUPY-1, !- Number of People Schedule Name + people, !- Number of People Calculation Method + 20, !- Number of People + , !- People per Floor Area {person/m2} + , !- Floor Area per Person {m2/person} + 0.3, !- Fraction Radiant + , !- Sensible Heat Fraction + ActSchd; !- Activity Level Schedule Name + + Lights, + SPACE5-1 Lights 1, !- Name + SPACE5-1, !- Zone or ZoneList or Space or SpaceList Name + LIGHTS-1, !- Schedule Name + LightingLevel, !- Design Level Calculation Method + 2964, !- Lighting Level {W} + , !- Watts per Zone Floor Area {W/m2} + , !- Watts per Person {W/person} + 0.2, !- Return Air Fraction + 0.59, !- Fraction Radiant + 0.2, !- Fraction Visible + 0, !- Fraction Replaceable + GeneralLights; !- End-Use Subcategory + + ElectricEquipment, + SPACE5-1 ElecEq 1, !- Name + SPACE5-1, !- Zone or ZoneList or Space or SpaceList Name + EQUIP-1, !- Schedule Name + EquipmentLevel, !- Design Level Calculation Method + 1976, !- Design Level {W} + , !- Watts per Zone Floor Area {W/m2} + , !- Watts per Person {W/person} + 0, !- Fraction Latent + 0.3, !- Fraction Radiant + 0; !- Fraction Lost + + BuildingSurface:Detailed, + C5-1, !- Name + CEILING, !- Surface Type + CLNG-1, !- Construction Name + SPACE5-1, !- Zone Name + , !- Space Name + Surface, !- Outside Boundary Condition + C5-1P, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 3.7,11.6,2.4, !- X,Y,Z ==> Vertex 1 {m} + 3.7,3.7,2.4, !- X,Y,Z ==> Vertex 2 {m} + 26.8,3.7,2.4, !- X,Y,Z ==> Vertex 3 {m} + 26.8,11.6,2.4; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + F5-1, !- Name + FLOOR, !- Surface Type + FLOOR-SLAB-1, !- Construction Name + SPACE5-1, !- Zone Name + , !- Space Name + Ground, !- Outside Boundary Condition + , !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 26.8,11.6,0.0, !- X,Y,Z ==> Vertex 1 {m} + 26.8,3.7,0.0, !- X,Y,Z ==> Vertex 2 {m} + 3.7,3.7,0.0, !- X,Y,Z ==> Vertex 3 {m} + 3.7,11.6,0.0; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + SB51, !- Name + WALL, !- Surface Type + INT-WALL-1, !- Construction Name + SPACE5-1, !- Zone Name + , !- Space Name + Surface, !- Outside Boundary Condition + SB15, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 3.7,3.7,2.4, !- X,Y,Z ==> Vertex 1 {m} + 3.7,3.7,0.0, !- X,Y,Z ==> Vertex 2 {m} + 26.8,3.7,0.0, !- X,Y,Z ==> Vertex 3 {m} + 26.8,3.7,2.4; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + SB52, !- Name + WALL, !- Surface Type + INT-WALL-1, !- Construction Name + SPACE5-1, !- Zone Name + , !- Space Name + Surface, !- Outside Boundary Condition + SB25, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 26.8,3.7,2.4, !- X,Y,Z ==> Vertex 1 {m} + 26.8,3.7,0.0, !- X,Y,Z ==> Vertex 2 {m} + 26.8,11.6,0.0, !- X,Y,Z ==> Vertex 3 {m} + 26.8,11.6,2.4; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + SB53, !- Name + WALL, !- Surface Type + INT-WALL-1, !- Construction Name + SPACE5-1, !- Zone Name + , !- Space Name + Surface, !- Outside Boundary Condition + SB35, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 26.8,11.6,2.4, !- X,Y,Z ==> Vertex 1 {m} + 26.8,11.6,0.0, !- X,Y,Z ==> Vertex 2 {m} + 3.7,11.6,0.0, !- X,Y,Z ==> Vertex 3 {m} + 3.7,11.6,2.4; !- X,Y,Z ==> Vertex 4 {m} + + BuildingSurface:Detailed, + SB54, !- Name + WALL, !- Surface Type + INT-WALL-1, !- Construction Name + SPACE5-1, !- Zone Name + , !- Space Name + Surface, !- Outside Boundary Condition + SB45, !- Outside Boundary Condition Object + NoSun, !- Sun Exposure + NoWind, !- Wind Exposure + 0.0, !- View Factor to Ground + 4, !- Number of Vertices + 3.7,11.6,2.4, !- X,Y,Z ==> Vertex 1 {m} + 3.7,11.6,0.0, !- X,Y,Z ==> Vertex 2 {m} + 3.7,3.7,0.0, !- X,Y,Z ==> Vertex 3 {m} + 3.7,3.7,2.4; !- X,Y,Z ==> Vertex 4 {m} + + Sizing:Parameters, + 1.0, !- Heating Sizing Factor + 1.0, !- Cooling Sizing Factor + ; !- Timesteps in Averaging Window + + Sizing:Zone, + SPACE1-1, !- Zone or ZoneList Name + SupplyAirTemperature, !- Zone Cooling Design Supply Air Temperature Input Method + 14., !- Zone Cooling Design Supply Air Temperature {C} + , !- Zone Cooling Design Supply Air Temperature Difference {deltaC} + SupplyAirTemperature, !- Zone Heating Design Supply Air Temperature Input Method + 50., !- Zone Heating Design Supply Air Temperature {C} + , !- Zone Heating Design Supply Air Temperature Difference {deltaC} + 0.009, !- Zone Cooling Design Supply Air Humidity Ratio {kgWater/kgDryAir} + 0.004, !- Zone Heating Design Supply Air Humidity Ratio {kgWater/kgDryAir} + SZ DSOA SPACE1-1, !- Design Specification Outdoor Air Object Name + 0.0, !- Zone Heating Sizing Factor + 0.0, !- Zone Cooling Sizing Factor + DesignDayWithLimit, !- Cooling Design Air Flow Method + , !- Cooling Design Air Flow Rate {m3/s} + , !- Cooling Minimum Air Flow per Zone Floor Area {m3/s-m2} + , !- Cooling Minimum Air Flow {m3/s} + , !- Cooling Minimum Air Flow Fraction + DesignDay, !- Heating Design Air Flow Method + , !- Heating Design Air Flow Rate {m3/s} + , !- Heating Maximum Air Flow per Zone Floor Area {m3/s-m2} + , !- Heating Maximum Air Flow {m3/s} + , !- Heating Maximum Air Flow Fraction + , !- Design Specification Zone Air Distribution Object Name + No, !- Account for Dedicated Outdoor Air System + NeutralSupplyAir, !- Dedicated Outdoor Air System Control Strategy + autosize, !- Dedicated Outdoor Air Low Setpoint Temperature for Design {C} + autosize; !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + + DesignSpecification:OutdoorAir, + SZ DSOA SPACE1-1, !- Name + sum, !- Outdoor Air Method + 0.00236, !- Outdoor Air Flow per Person {m3/s-person} + 0.000305, !- Outdoor Air Flow per Zone Floor Area {m3/s-m2} + 0.0; !- Outdoor Air Flow per Zone {m3/s} + + Sizing:Zone, + SPACE2-1, !- Zone or ZoneList Name + SupplyAirTemperature, !- Zone Cooling Design Supply Air Temperature Input Method + 14., !- Zone Cooling Design Supply Air Temperature {C} + , !- Zone Cooling Design Supply Air Temperature Difference {deltaC} + SupplyAirTemperature, !- Zone Heating Design Supply Air Temperature Input Method + 50., !- Zone Heating Design Supply Air Temperature {C} + , !- Zone Heating Design Supply Air Temperature Difference {deltaC} + 0.009, !- Zone Cooling Design Supply Air Humidity Ratio {kgWater/kgDryAir} + 0.004, !- Zone Heating Design Supply Air Humidity Ratio {kgWater/kgDryAir} + SZ DSOA SPACE2-1, !- Design Specification Outdoor Air Object Name + 0.0, !- Zone Heating Sizing Factor + 0.0, !- Zone Cooling Sizing Factor + DesignDayWithLimit, !- Cooling Design Air Flow Method + , !- Cooling Design Air Flow Rate {m3/s} + , !- Cooling Minimum Air Flow per Zone Floor Area {m3/s-m2} + , !- Cooling Minimum Air Flow {m3/s} + , !- Cooling Minimum Air Flow Fraction + DesignDay, !- Heating Design Air Flow Method + , !- Heating Design Air Flow Rate {m3/s} + , !- Heating Maximum Air Flow per Zone Floor Area {m3/s-m2} + , !- Heating Maximum Air Flow {m3/s} + , !- Heating Maximum Air Flow Fraction + , !- Design Specification Zone Air Distribution Object Name + No, !- Account for Dedicated Outdoor Air System + NeutralSupplyAir, !- Dedicated Outdoor Air System Control Strategy + autosize, !- Dedicated Outdoor Air Low Setpoint Temperature for Design {C} + autosize; !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + + DesignSpecification:OutdoorAir, + SZ DSOA SPACE2-1, !- Name + sum, !- Outdoor Air Method + 0.00236, !- Outdoor Air Flow per Person {m3/s-person} + 0.000305, !- Outdoor Air Flow per Zone Floor Area {m3/s-m2} + 0.0; !- Outdoor Air Flow per Zone {m3/s} + + Sizing:Zone, + SPACE3-1, !- Zone or ZoneList Name + SupplyAirTemperature, !- Zone Cooling Design Supply Air Temperature Input Method + 14., !- Zone Cooling Design Supply Air Temperature {C} + , !- Zone Cooling Design Supply Air Temperature Difference {deltaC} + SupplyAirTemperature, !- Zone Heating Design Supply Air Temperature Input Method + 50., !- Zone Heating Design Supply Air Temperature {C} + , !- Zone Heating Design Supply Air Temperature Difference {deltaC} + 0.009, !- Zone Cooling Design Supply Air Humidity Ratio {kgWater/kgDryAir} + 0.004, !- Zone Heating Design Supply Air Humidity Ratio {kgWater/kgDryAir} + SZ DSOA SPACE3-1, !- Design Specification Outdoor Air Object Name + 0.0, !- Zone Heating Sizing Factor + 0.0, !- Zone Cooling Sizing Factor + DesignDayWithLimit, !- Cooling Design Air Flow Method + , !- Cooling Design Air Flow Rate {m3/s} + , !- Cooling Minimum Air Flow per Zone Floor Area {m3/s-m2} + , !- Cooling Minimum Air Flow {m3/s} + , !- Cooling Minimum Air Flow Fraction + DesignDay, !- Heating Design Air Flow Method + , !- Heating Design Air Flow Rate {m3/s} + , !- Heating Maximum Air Flow per Zone Floor Area {m3/s-m2} + , !- Heating Maximum Air Flow {m3/s} + , !- Heating Maximum Air Flow Fraction + , !- Design Specification Zone Air Distribution Object Name + No, !- Account for Dedicated Outdoor Air System + NeutralSupplyAir, !- Dedicated Outdoor Air System Control Strategy + autosize, !- Dedicated Outdoor Air Low Setpoint Temperature for Design {C} + autosize; !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + + DesignSpecification:OutdoorAir, + SZ DSOA SPACE3-1, !- Name + sum, !- Outdoor Air Method + 0.00236, !- Outdoor Air Flow per Person {m3/s-person} + 0.000305, !- Outdoor Air Flow per Zone Floor Area {m3/s-m2} + 0.0; !- Outdoor Air Flow per Zone {m3/s} + + Sizing:Zone, + SPACE4-1, !- Zone or ZoneList Name + SupplyAirTemperature, !- Zone Cooling Design Supply Air Temperature Input Method + 14., !- Zone Cooling Design Supply Air Temperature {C} + , !- Zone Cooling Design Supply Air Temperature Difference {deltaC} + SupplyAirTemperature, !- Zone Heating Design Supply Air Temperature Input Method + 50., !- Zone Heating Design Supply Air Temperature {C} + , !- Zone Heating Design Supply Air Temperature Difference {deltaC} + 0.009, !- Zone Cooling Design Supply Air Humidity Ratio {kgWater/kgDryAir} + 0.004, !- Zone Heating Design Supply Air Humidity Ratio {kgWater/kgDryAir} + SZ DSOA SPACE4-1, !- Design Specification Outdoor Air Object Name + 0.0, !- Zone Heating Sizing Factor + 0.0, !- Zone Cooling Sizing Factor + DesignDayWithLimit, !- Cooling Design Air Flow Method + , !- Cooling Design Air Flow Rate {m3/s} + , !- Cooling Minimum Air Flow per Zone Floor Area {m3/s-m2} + , !- Cooling Minimum Air Flow {m3/s} + , !- Cooling Minimum Air Flow Fraction + DesignDay, !- Heating Design Air Flow Method + , !- Heating Design Air Flow Rate {m3/s} + , !- Heating Maximum Air Flow per Zone Floor Area {m3/s-m2} + , !- Heating Maximum Air Flow {m3/s} + , !- Heating Maximum Air Flow Fraction + , !- Design Specification Zone Air Distribution Object Name + No, !- Account for Dedicated Outdoor Air System + NeutralSupplyAir, !- Dedicated Outdoor Air System Control Strategy + autosize, !- Dedicated Outdoor Air Low Setpoint Temperature for Design {C} + autosize; !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + + DesignSpecification:OutdoorAir, + SZ DSOA SPACE4-1, !- Name + sum, !- Outdoor Air Method + 0.00236, !- Outdoor Air Flow per Person {m3/s-person} + 0.000305, !- Outdoor Air Flow per Zone Floor Area {m3/s-m2} + 0.0; !- Outdoor Air Flow per Zone {m3/s} + + Sizing:Zone, + SPACE5-1, !- Zone or ZoneList Name + SupplyAirTemperature, !- Zone Cooling Design Supply Air Temperature Input Method + 14., !- Zone Cooling Design Supply Air Temperature {C} + , !- Zone Cooling Design Supply Air Temperature Difference {deltaC} + SupplyAirTemperature, !- Zone Heating Design Supply Air Temperature Input Method + 50., !- Zone Heating Design Supply Air Temperature {C} + , !- Zone Heating Design Supply Air Temperature Difference {deltaC} + 0.009, !- Zone Cooling Design Supply Air Humidity Ratio {kgWater/kgDryAir} + 0.004, !- Zone Heating Design Supply Air Humidity Ratio {kgWater/kgDryAir} + SZ DSOA SPACE5-1, !- Design Specification Outdoor Air Object Name + 0.0, !- Zone Heating Sizing Factor + 0.0, !- Zone Cooling Sizing Factor + DesignDayWithLimit, !- Cooling Design Air Flow Method + , !- Cooling Design Air Flow Rate {m3/s} + , !- Cooling Minimum Air Flow per Zone Floor Area {m3/s-m2} + , !- Cooling Minimum Air Flow {m3/s} + , !- Cooling Minimum Air Flow Fraction + DesignDay, !- Heating Design Air Flow Method + , !- Heating Design Air Flow Rate {m3/s} + , !- Heating Maximum Air Flow per Zone Floor Area {m3/s-m2} + , !- Heating Maximum Air Flow {m3/s} + , !- Heating Maximum Air Flow Fraction + , !- Design Specification Zone Air Distribution Object Name + No, !- Account for Dedicated Outdoor Air System + NeutralSupplyAir, !- Dedicated Outdoor Air System Control Strategy + autosize, !- Dedicated Outdoor Air Low Setpoint Temperature for Design {C} + autosize; !- Dedicated Outdoor Air High Setpoint Temperature for Design {C} + + DesignSpecification:OutdoorAir, + SZ DSOA SPACE5-1, !- Name + sum, !- Outdoor Air Method + 0.00236, !- Outdoor Air Flow per Person {m3/s-person} + 0.000305, !- Outdoor Air Flow per Zone Floor Area {m3/s-m2} + 0.0; !- Outdoor Air Flow per Zone {m3/s} + + Sizing:System, + VAV Sys 1, !- AirLoop Name + sensible, !- Type of Load to Size On + autosize, !- Design Outdoor Air Flow Rate {m3/s} + 0.3, !- Central Heating Maximum System Air Flow Ratio + 4.5, !- Preheat Design Temperature {C} + 0.008, !- Preheat Design Humidity Ratio {kgWater/kgDryAir} + 11.0, !- Precool Design Temperature {C} + 0.008, !- Precool Design Humidity Ratio {kgWater/kgDryAir} + 12.8, !- Central Cooling Design Supply Air Temperature {C} + 16.7, !- Central Heating Design Supply Air Temperature {C} + noncoincident, !- Type of Zone Sum to Use + no, !- 100% Outdoor Air in Cooling + no, !- 100% Outdoor Air in Heating + 0.008, !- Central Cooling Design Supply Air Humidity Ratio {kgWater/kgDryAir} + 0.008, !- Central Heating Design Supply Air Humidity Ratio {kgWater/kgDryAir} + DesignDay, !- Cooling Supply Air Flow Rate Method + 0, !- 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 Cooling Capacity {m3/s-W} + DesignDay, !- Heating Supply Air Flow Rate Method + 0, !- 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 Fraction of Autosized Cooling Supply Air Flow Rate + , !- Heating Supply Air Flow Rate Per Unit Heating Capacity {m3/s-W} + , !- System Outdoor Air Method + 1.0, !- Zone Maximum Outdoor Air Fraction {dimensionless} + CoolingDesignCapacity, !- Cooling Design Capacity Method + autosize, !- Cooling Design Capacity {W} + , !- Cooling Design Capacity Per Floor Area {W/m2} + , !- Fraction of Autosized Cooling Design Capacity + HeatingDesignCapacity, !- Heating Design Capacity Method + autosize, !- Heating Design Capacity {W} + , !- Heating Design Capacity Per Floor Area {W/m2} + , !- Fraction of Autosized Heating Design Capacity + VAV; !- Central Cooling Capacity Control Method + + Sizing:Plant, + Hot Water Loop, !- Plant or Condenser Loop Name + heating, !- Loop Type + 82., !- Design Loop Exit Temperature {C} + 11; !- Loop Design Temperature Difference {deltaC} + + Sizing:Plant, + Chilled Water Loop, !- Plant or Condenser Loop Name + cooling, !- Loop Type + 7.00, !- Design Loop Exit Temperature {C} + 4.00; !- Loop Design Temperature Difference {deltaC} + + Schedule:Compact, + Htg-SetP-Sch, !- Name + Temperature, !- Schedule Type Limits Name + Through: 12/31, !- Field 1 + For: SummerDesignDay, !- Field 2 + Until: 24:00,16.7, !- Field 3 + For: WinterDesignDay, !- Field 5 + Until: 24:00,22.2, !- Field 6 + For: WeekDays, !- Field 8 + Until: 6:00,16.7, !- Field 9 + Until: 20:00,22.2, !- Field 11 + Until: 24:00,16.7, !- Field 13 + For: WeekEnds Holiday, !- Field 15 + Until: 24:00,16.7, !- Field 16 + For: AllOtherDays, !- Field 18 + Until: 24:00,16.7; !- Field 19 + + Schedule:Compact, + PlenumHtg-SetP-Sch, !- Name + Temperature, !- Schedule Type Limits Name + Through: 12/31, !- Field 1 + For: AllDays, !- Field 2 + Until: 24:00,12.8; !- Field 3 + + Schedule:Compact, + Clg-SetP-Sch, !- Name + Temperature, !- Schedule Type Limits Name + Through: 12/31, !- Field 1 + For: SummerDesignDay, !- Field 2 + Until: 24:00,23.9, !- Field 3 + For: WinterDesignDay, !- Field 5 + Until: 24:00,29.4, !- Field 6 + For: WeekDays, !- Field 8 + Until: 6:00,29.4, !- Field 9 + Until: 20:00,23.9, !- Field 11 + Until: 24:00,29.4, !- Field 13 + For: WeekEnds Holiday, !- Field 15 + Until: 24:00,29.4, !- Field 16 + For: AllOtherDays, !- Field 18 + Until: 24:00,29.4; !- Field 19 + + Schedule:Compact, + PlenumClg-SetP-Sch, !- Name + Temperature, !- Schedule Type Limits Name + Through: 12/31, !- Field 1 + For: AllDays, !- Field 2 + Until: 24:00,40.0; !- Field 3 + + Schedule:Compact, + Zone Control Type Sched, !- Name + Control Type, !- Schedule Type Limits Name + Through: 12/31, !- Field 1 + For: SummerDesignDay, !- Field 2 + Until: 24:00,2, !- Field 3 + For: WinterDesignDay, !- Field 5 + Until: 24:00,1, !- Field 6 + For: AllOtherDays, !- Field 8 + Until: 24:00,4; !- Field 9 + + Schedule:Compact, + Min OA Sched, !- Name + Fraction, !- Schedule Type Limits Name + Through: 12/31, !- Field 1 + For: Weekdays, !- Field 2 + Until: 6:00,0.02, !- Field 3 + Until: 20:00,1.0, !- Field 5 + Until: 24:00,0.02, !- Field 7 + For: AllOtherDays, !- Field 9 + Until: 24:00,0.02; !- Field 10 + + Schedule:Compact, + FanAvailSched, !- Name + Fraction, !- Schedule Type Limits Name + Through: 3/31, !- Field 1 + For: AllDays, !- Field 2 + Until: 24:00,1.0, !- Field 3 + Through: 9/30, !- Field 5 + For: WeekDays, !- Field 6 + Until: 6:00,0.0, !- Field 7 + Until: 20:00,1.0, !- Field 9 + Until: 24:00,0.0, !- Field 11 + For: SummerDesignDay WinterDesignDay, !- Field 13 + Until: 24:00,1.0, !- Field 14 + For: AllOtherDays, !- Field 16 + Until: 24:00,0.0, !- Field 17 + Through: 12/31, !- Field 19 + For: AllDays, !- Field 20 + Until: 24:00,1.0; !- Field 21 + + Schedule:Compact, + CoolingCoilAvailSched, !- Name + Fraction, !- Schedule Type Limits Name + Through: 12/31, !- Field 1 + For: WeekDays, !- Field 2 + Until: 6:00,0.0, !- Field 3 + Until: 20:00,1.0, !- Field 5 + Until: 24:00,0.0, !- Field 7 + For: SummerDesignDay WinterDesignDay, !- Field 9 + Until: 24:00,1.0, !- Field 10 + For: AllOtherDays, !- Field 12 + Until: 24:00,0.0; !- Field 13 + + Schedule:Compact, + CoolingPumpAvailSched, !- Name + Fraction, !- Schedule Type Limits Name + Through: 12/31, !- Field 1 + For: AllDays, !- Field 2 + Until: 24:00,1.0; !- Field 3 + + Schedule:Compact, + ReheatCoilAvailSched, !- Name + Fraction, !- Schedule Type Limits Name + Through: 3/31, !- Field 1 + For: AllDays, !- Field 2 + Until: 24:00,1.0, !- Field 3 + Through: 9/30, !- Field 5 + For: WeekDays, !- Field 6 + Until: 6:00,0.0, !- Field 7 + Until: 20:00,1.0, !- Field 9 + Until: 24:00,0.0, !- Field 11 + For: SummerDesignDay WinterDesignDay, !- Field 13 + Until: 24:00,1.0, !- Field 14 + For: AllOtherDays, !- Field 16 + Until: 24:00,0.0, !- Field 17 + Through: 12/31, !- Field 19 + For: AllDays, !- Field 20 + Until: 24:00,1.0; !- Field 21 + + Schedule:Compact, + CW Loop Temp Schedule, !- Name + Temperature, !- Schedule Type Limits Name + Through: 12/31, !- Field 1 + For: AllDays, !- Field 2 + Until: 24:00,7.22; !- Field 3 + + Schedule:Compact, + HW Loop Temp Schedule, !- Name + Temperature, !- Schedule Type Limits Name + Through: 12/31, !- Field 1 + For: AllDays, !- Field 2 + Until: 24:00,82; !- Field 3 + + Schedule:Compact, + PlantOnSched, !- Name + Fraction, !- Schedule Type Limits Name + Through: 12/31, !- Field 1 + For: AllDays, !- Field 2 + Until: 24:00,1.0; !- Field 3 + + Schedule:Compact, + Seasonal Reset Supply Air Temp Sch, !- Name + Temperature, !- Schedule Type Limits Name + Through: 3/31, !- Field 1 + For: AllDays, !- Field 2 + Until: 24:00,16.0, !- Field 3 + Through: 9/30, !- Field 5 + For: AllDays, !- Field 6 + Until: 24:00,13.0, !- Field 7 + Through: 12/31, !- Field 9 + For: AllDays, !- Field 10 + Until: 24:00,16.0; !- Field 11 + + Schedule:Compact, + OA Cooling Supply Air Temp Sch, !- Name + Temperature, !- Schedule Type Limits Name + Through: 12/31, !- Field 1 + For: AllDays, !- Field 2 + Until: 24:00,11.5; !- Field 3 + + Schedule:Compact, + OA Heating Supply Air Temp Sch, !- Name + Temperature, !- Schedule Type Limits Name + Through: 12/31, !- Field 1 + For: AllDays, !- Field 2 + Until: 24:00,4.5; !- Field 3 + + OutdoorAir:NodeList, + OutsideAirInletNodes; !- Node or NodeList Name 1 + + NodeList, + OutsideAirInletNodes, !- Name + Outside Air Inlet Node 1;!- Node 1 Name + + ZoneHVAC:EquipmentConnections, + SPACE1-1, !- Zone Name + SPACE1-1 Eq, !- Zone Conditioning Equipment List Name + SPACE1-1 In Node, !- Zone Air Inlet Node or NodeList Name + , !- Zone Air Exhaust Node or NodeList Name + SPACE1-1 Node, !- Zone Air Node Name + SPACE1-1 Out Node; !- Zone Return Air Node or NodeList Name + + ZoneHVAC:EquipmentConnections, + SPACE2-1, !- Zone Name + SPACE2-1 Eq, !- Zone Conditioning Equipment List Name + SPACE2-1 In Node, !- Zone Air Inlet Node or NodeList Name + , !- Zone Air Exhaust Node or NodeList Name + SPACE2-1 Node, !- Zone Air Node Name + SPACE2-1 Out Node; !- Zone Return Air Node or NodeList Name + + ZoneHVAC:EquipmentConnections, + SPACE3-1, !- Zone Name + SPACE3-1 Eq, !- Zone Conditioning Equipment List Name + SPACE3-1 In Node, !- Zone Air Inlet Node or NodeList Name + , !- Zone Air Exhaust Node or NodeList Name + SPACE3-1 Node, !- Zone Air Node Name + SPACE3-1 Out Node; !- Zone Return Air Node or NodeList Name + + ZoneHVAC:EquipmentConnections, + SPACE4-1, !- Zone Name + SPACE4-1 Eq, !- Zone Conditioning Equipment List Name + SPACE4-1 In Node, !- Zone Air Inlet Node or NodeList Name + , !- Zone Air Exhaust Node or NodeList Name + SPACE4-1 Node, !- Zone Air Node Name + SPACE4-1 Out Node; !- Zone Return Air Node or NodeList Name + + ZoneHVAC:EquipmentConnections, + SPACE5-1, !- Zone Name + SPACE5-1 Eq, !- Zone Conditioning Equipment List Name + SPACE5-1 In Node, !- Zone Air Inlet Node or NodeList Name + , !- Zone Air Exhaust Node or NodeList Name + SPACE5-1 Node, !- Zone Air Node Name + SPACE5-1 Out Node; !- Zone Return Air Node or NodeList Name + + ZoneControl:Thermostat, + SPACE1-1 Control, !- Name + SPACE1-1, !- Zone or ZoneList Name + Zone Control Type Sched, !- Control Type Schedule Name + ThermostatSetpoint:SingleCooling, !- Control 1 Object Type + CoolingSetPoint, !- Control 1 Name + ThermostatSetpoint:SingleHeating, !- Control 2 Object Type + HeatingSetpoint, !- Control 2 Name + ThermostatSetpoint:DualSetpoint, !- Control 3 Object Type + DualSetPoint; !- Control 3 Name + + ZoneControl:Thermostat, + SPACE2-1 Control, !- Name + SPACE2-1, !- Zone or ZoneList Name + Zone Control Type Sched, !- Control Type Schedule Name + ThermostatSetpoint:SingleCooling, !- Control 1 Object Type + CoolingSetPoint, !- Control 1 Name + ThermostatSetpoint:SingleHeating, !- Control 2 Object Type + HeatingSetpoint, !- Control 2 Name + ThermostatSetpoint:DualSetpoint, !- Control 3 Object Type + DualSetPoint; !- Control 3 Name + + ZoneControl:Thermostat, + SPACE3-1 Control, !- Name + SPACE3-1, !- Zone or ZoneList Name + Zone Control Type Sched, !- Control Type Schedule Name + ThermostatSetpoint:SingleCooling, !- Control 1 Object Type + CoolingSetPoint, !- Control 1 Name + ThermostatSetpoint:SingleHeating, !- Control 2 Object Type + HeatingSetpoint, !- Control 2 Name + ThermostatSetpoint:DualSetpoint, !- Control 3 Object Type + DualSetPoint; !- Control 3 Name + + ZoneControl:Thermostat, + SPACE4-1 Control, !- Name + SPACE4-1, !- Zone or ZoneList Name + Zone Control Type Sched, !- Control Type Schedule Name + ThermostatSetpoint:SingleCooling, !- Control 1 Object Type + CoolingSetPoint, !- Control 1 Name + ThermostatSetpoint:SingleHeating, !- Control 2 Object Type + HeatingSetpoint, !- Control 2 Name + ThermostatSetpoint:DualSetpoint, !- Control 3 Object Type + DualSetPoint; !- Control 3 Name + + ZoneControl:Thermostat, + SPACE5-1 Control, !- Name + SPACE5-1, !- Zone or ZoneList Name + Zone Control Type Sched, !- Control Type Schedule Name + ThermostatSetpoint:SingleCooling, !- Control 1 Object Type + CoolingSetPoint, !- Control 1 Name + ThermostatSetpoint:SingleHeating, !- Control 2 Object Type + HeatingSetpoint, !- Control 2 Name + ThermostatSetpoint:DualSetpoint, !- Control 3 Object Type + DualSetPoint; !- Control 3 Name + + ThermostatSetpoint:SingleHeating, + HeatingSetpoint, !- Name + Htg-SetP-Sch; !- Setpoint Temperature Schedule Name + + ThermostatSetpoint:SingleCooling, + CoolingSetpoint, !- Name + Clg-SetP-Sch; !- Setpoint Temperature Schedule Name + + ThermostatSetpoint:SingleHeating, + PlenumHeatingSetpoint, !- Name + PlenumHtg-SetP-Sch; !- Setpoint Temperature Schedule Name + + ThermostatSetpoint:SingleCooling, + PlenumCoolingSetpoint, !- Name + PlenumClg-SetP-Sch; !- Setpoint Temperature Schedule Name + + ThermostatSetpoint:DualSetpoint, + DualSetPoint, !- Name + Htg-SetP-Sch, !- Heating Setpoint Temperature Schedule Name + Clg-SetP-Sch; !- Cooling Setpoint Temperature Schedule Name + + ZoneHVAC:EquipmentList, + SPACE1-1 Eq, !- Name + SequentialLoad, !- Load Distribution Scheme + ZoneHVAC:AirDistributionUnit, !- Zone Equipment 1 Object Type + SPACE1-1 ATU, !- Zone Equipment 1 Name + 1, !- Zone Equipment 1 Cooling Sequence + 1, !- Zone Equipment 1 Heating or No-Load Sequence + , !- Zone Equipment 1 Sequential Cooling Fraction Schedule Name + ; !- Zone Equipment 1 Sequential Heating Fraction Schedule Name + + ZoneHVAC:EquipmentList, + SPACE2-1 Eq, !- Name + SequentialLoad, !- Load Distribution Scheme + ZoneHVAC:AirDistributionUnit, !- Zone Equipment 1 Object Type + SPACE2-1 ATU, !- Zone Equipment 1 Name + 1, !- Zone Equipment 1 Cooling Sequence + 1, !- Zone Equipment 1 Heating or No-Load Sequence + , !- Zone Equipment 1 Sequential Cooling Fraction Schedule Name + ; !- Zone Equipment 1 Sequential Heating Fraction Schedule Name + + ZoneHVAC:EquipmentList, + SPACE3-1 Eq, !- Name + SequentialLoad, !- Load Distribution Scheme + ZoneHVAC:AirDistributionUnit, !- Zone Equipment 1 Object Type + SPACE3-1 ATU, !- Zone Equipment 1 Name + 1, !- Zone Equipment 1 Cooling Sequence + 1, !- Zone Equipment 1 Heating or No-Load Sequence + , !- Zone Equipment 1 Sequential Cooling Fraction Schedule Name + ; !- Zone Equipment 1 Sequential Heating Fraction Schedule Name + + ZoneHVAC:EquipmentList, + SPACE4-1 Eq, !- Name + SequentialLoad, !- Load Distribution Scheme + ZoneHVAC:AirDistributionUnit, !- Zone Equipment 1 Object Type + SPACE4-1 ATU, !- Zone Equipment 1 Name + 1, !- Zone Equipment 1 Cooling Sequence + 1, !- Zone Equipment 1 Heating or No-Load Sequence + , !- Zone Equipment 1 Sequential Cooling Fraction Schedule Name + ; !- Zone Equipment 1 Sequential Heating Fraction Schedule Name + + ZoneHVAC:EquipmentList, + SPACE5-1 Eq, !- Name + SequentialLoad, !- Load Distribution Scheme + ZoneHVAC:AirDistributionUnit, !- Zone Equipment 1 Object Type + SPACE5-1 ATU, !- Zone Equipment 1 Name + 1, !- Zone Equipment 1 Cooling Sequence + 1, !- Zone Equipment 1 Heating or No-Load Sequence + , !- Zone Equipment 1 Sequential Cooling Fraction Schedule Name + ; !- Zone Equipment 1 Sequential Heating Fraction Schedule Name + + ZoneHVAC:AirDistributionUnit, + SPACE1-1 ATU, !- Name + SPACE1-1 In Node, !- Air Distribution Unit Outlet Node Name + AirTerminal:SingleDuct:VAV:Reheat, !- Air Terminal Object Type + SPACE1-1 VAV Reheat; !- Air Terminal Name + + ZoneHVAC:AirDistributionUnit, + SPACE2-1 ATU, !- Name + SPACE2-1 In Node, !- Air Distribution Unit Outlet Node Name + AirTerminal:SingleDuct:VAV:Reheat, !- Air Terminal Object Type + SPACE2-1 VAV Reheat; !- Air Terminal Name + + ZoneHVAC:AirDistributionUnit, + SPACE3-1 ATU, !- Name + SPACE3-1 In Node, !- Air Distribution Unit Outlet Node Name + AirTerminal:SingleDuct:VAV:Reheat, !- Air Terminal Object Type + SPACE3-1 VAV Reheat; !- Air Terminal Name + + ZoneHVAC:AirDistributionUnit, + SPACE4-1 ATU, !- Name + SPACE4-1 In Node, !- Air Distribution Unit Outlet Node Name + AirTerminal:SingleDuct:VAV:Reheat, !- Air Terminal Object Type + SPACE4-1 VAV Reheat; !- Air Terminal Name + + ZoneHVAC:AirDistributionUnit, + SPACE5-1 ATU, !- Name + SPACE5-1 In Node, !- Air Distribution Unit Outlet Node Name + AirTerminal:SingleDuct:VAV:Reheat, !- Air Terminal Object Type + SPACE5-1 VAV Reheat; !- Air Terminal Name + + AirTerminal:SingleDuct:VAV:Reheat, + SPACE1-1 VAV Reheat, !- Name + ReheatCoilAvailSched, !- Availability Schedule Name + SPACE1-1 Zone Coil Air In Node, !- Damper Air Outlet Node Name + SPACE1-1 ATU In Node, !- Air Inlet Node Name + autosize, !- Maximum Air Flow Rate {m3/s} + Constant, !- Zone Minimum Air Flow Input Method + 0.3, !- Constant Minimum Air Flow Fraction + , !- Fixed Minimum Air Flow Rate {m3/s} + , !- Minimum Air Flow Fraction Schedule Name + Coil:Heating:Water, !- Reheat Coil Object Type + SPACE1-1 Zone Coil, !- Reheat Coil Name + autosize, !- Maximum Hot Water or Steam Flow Rate {m3/s} + 0.0, !- Minimum Hot Water or Steam Flow Rate {m3/s} + SPACE1-1 In Node, !- Air Outlet Node Name + 0.001, !- Convergence Tolerance + NORMAL, !- Damper Heating Action + AUTOCALCULATE, !- Maximum Flow per Zone Floor Area During Reheat {m3/s-m2} + AUTOCALCULATE; !- Maximum Flow Fraction During Reheat + + AirTerminal:SingleDuct:VAV:Reheat, + SPACE2-1 VAV Reheat, !- Name + ReheatCoilAvailSched, !- Availability Schedule Name + SPACE2-1 Zone Coil Air In Node, !- Damper Air Outlet Node Name + SPACE2-1 ATU In Node, !- Air Inlet Node Name + autosize, !- Maximum Air Flow Rate {m3/s} + Constant, !- Zone Minimum Air Flow Input Method + 0.3, !- Constant Minimum Air Flow Fraction + , !- Fixed Minimum Air Flow Rate {m3/s} + , !- Minimum Air Flow Fraction Schedule Name + Coil:Heating:Water, !- Reheat Coil Object Type + SPACE2-1 Zone Coil, !- Reheat Coil Name + autosize, !- Maximum Hot Water or Steam Flow Rate {m3/s} + 0.0, !- Minimum Hot Water or Steam Flow Rate {m3/s} + SPACE2-1 In Node, !- Air Outlet Node Name + 0.001, !- Convergence Tolerance + NORMAL, !- Damper Heating Action + AUTOCALCULATE, !- Maximum Flow per Zone Floor Area During Reheat {m3/s-m2} + AUTOCALCULATE; !- Maximum Flow Fraction During Reheat + + AirTerminal:SingleDuct:VAV:Reheat, + SPACE3-1 VAV Reheat, !- Name + ReheatCoilAvailSched, !- Availability Schedule Name + SPACE3-1 Zone Coil Air In Node, !- Damper Air Outlet Node Name + SPACE3-1 ATU In Node, !- Air Inlet Node Name + autosize, !- Maximum Air Flow Rate {m3/s} + Constant, !- Zone Minimum Air Flow Input Method + 0.3, !- Constant Minimum Air Flow Fraction + , !- Fixed Minimum Air Flow Rate {m3/s} + , !- Minimum Air Flow Fraction Schedule Name + Coil:Heating:Water, !- Reheat Coil Object Type + SPACE3-1 Zone Coil, !- Reheat Coil Name + autosize, !- Maximum Hot Water or Steam Flow Rate {m3/s} + 0.0, !- Minimum Hot Water or Steam Flow Rate {m3/s} + SPACE3-1 In Node, !- Air Outlet Node Name + 0.001, !- Convergence Tolerance + NORMAL, !- Damper Heating Action + AUTOCALCULATE, !- Maximum Flow per Zone Floor Area During Reheat {m3/s-m2} + AUTOCALCULATE; !- Maximum Flow Fraction During Reheat + + AirTerminal:SingleDuct:VAV:Reheat, + SPACE4-1 VAV Reheat, !- Name + ReheatCoilAvailSched, !- Availability Schedule Name + SPACE4-1 Zone Coil Air In Node, !- Damper Air Outlet Node Name + SPACE4-1 ATU In Node, !- Air Inlet Node Name + autosize, !- Maximum Air Flow Rate {m3/s} + Constant, !- Zone Minimum Air Flow Input Method + 0.3, !- Constant Minimum Air Flow Fraction + , !- Fixed Minimum Air Flow Rate {m3/s} + , !- Minimum Air Flow Fraction Schedule Name + Coil:Heating:Water, !- Reheat Coil Object Type + SPACE4-1 Zone Coil, !- Reheat Coil Name + autosize, !- Maximum Hot Water or Steam Flow Rate {m3/s} + 0.0, !- Minimum Hot Water or Steam Flow Rate {m3/s} + SPACE4-1 In Node, !- Air Outlet Node Name + 0.001, !- Convergence Tolerance + NORMAL, !- Damper Heating Action + AUTOCALCULATE, !- Maximum Flow per Zone Floor Area During Reheat {m3/s-m2} + AUTOCALCULATE; !- Maximum Flow Fraction During Reheat + + AirTerminal:SingleDuct:VAV:Reheat, + SPACE5-1 VAV Reheat, !- Name + ReheatCoilAvailSched, !- Availability Schedule Name + SPACE5-1 Zone Coil Air In Node, !- Damper Air Outlet Node Name + SPACE5-1 ATU In Node, !- Air Inlet Node Name + autosize, !- Maximum Air Flow Rate {m3/s} + Constant, !- Zone Minimum Air Flow Input Method + 0.3, !- Constant Minimum Air Flow Fraction + , !- Fixed Minimum Air Flow Rate {m3/s} + , !- Minimum Air Flow Fraction Schedule Name + Coil:Heating:Water, !- Reheat Coil Object Type + SPACE5-1 Zone Coil, !- Reheat Coil Name + autosize, !- Maximum Hot Water or Steam Flow Rate {m3/s} + 0.0, !- Minimum Hot Water or Steam Flow Rate {m3/s} + SPACE5-1 In Node, !- Air Outlet Node Name + 0.001, !- Convergence Tolerance + NORMAL, !- Damper Heating Action + AUTOCALCULATE, !- Maximum Flow per Zone Floor Area During Reheat {m3/s-m2} + AUTOCALCULATE; !- Maximum Flow Fraction During Reheat + + Coil:Heating:Water, + SPACE1-1 Zone Coil, !- Name + ReheatCoilAvailSched, !- Availability Schedule Name + autosize, !- U-Factor Times Area Value {W/K} + autosize, !- Maximum Water Flow Rate {m3/s} + SPACE1-1 Zone Coil Water In Node, !- Water Inlet Node Name + SPACE1-1 Zone Coil Water Out Node, !- Water Outlet Node Name + SPACE1-1 Zone Coil Air In Node, !- Air Inlet Node Name + SPACE1-1 In Node, !- Air Outlet Node Name + UFactorTimesAreaAndDesignWaterFlowRate, !- Performance Input Method + autosize, !- Rated Capacity {W} + 82.2, !- Rated Inlet Water Temperature {C} + 16.6, !- Rated Inlet Air Temperature {C} + 71.1, !- Rated Outlet Water Temperature {C} + 32.2, !- Rated Outlet Air Temperature {C} + , !- Rated Ratio for Air and Water Convection + 11; !- Design Water Temperature Difference {deltaC} + + Coil:Heating:Water, + SPACE2-1 Zone Coil, !- Name + ReheatCoilAvailSched, !- Availability Schedule Name + autosize, !- U-Factor Times Area Value {W/K} + autosize, !- Maximum Water Flow Rate {m3/s} + SPACE2-1 Zone Coil Water In Node, !- Water Inlet Node Name + SPACE2-1 Zone Coil Water Out Node, !- Water Outlet Node Name + SPACE2-1 Zone Coil Air In Node, !- Air Inlet Node Name + SPACE2-1 In Node, !- Air Outlet Node Name + UFactorTimesAreaAndDesignWaterFlowRate, !- Performance Input Method + autosize, !- Rated Capacity {W} + 82.2, !- Rated Inlet Water Temperature {C} + 16.6, !- Rated Inlet Air Temperature {C} + 71.1, !- Rated Outlet Water Temperature {C} + 32.2, !- Rated Outlet Air Temperature {C} + , !- Rated Ratio for Air and Water Convection + 11; !- Design Water Temperature Difference {deltaC} + + Coil:Heating:Water, + SPACE3-1 Zone Coil, !- Name + ReheatCoilAvailSched, !- Availability Schedule Name + autosize, !- U-Factor Times Area Value {W/K} + autosize, !- Maximum Water Flow Rate {m3/s} + SPACE3-1 Zone Coil Water In Node, !- Water Inlet Node Name + SPACE3-1 Zone Coil Water Out Node, !- Water Outlet Node Name + SPACE3-1 Zone Coil Air In Node, !- Air Inlet Node Name + SPACE3-1 In Node, !- Air Outlet Node Name + UFactorTimesAreaAndDesignWaterFlowRate, !- Performance Input Method + autosize, !- Rated Capacity {W} + 82.2, !- Rated Inlet Water Temperature {C} + 16.6, !- Rated Inlet Air Temperature {C} + 71.1, !- Rated Outlet Water Temperature {C} + 32.2, !- Rated Outlet Air Temperature {C} + , !- Rated Ratio for Air and Water Convection + 11; !- Design Water Temperature Difference {deltaC} + + Coil:Heating:Water, + SPACE4-1 Zone Coil, !- Name + ReheatCoilAvailSched, !- Availability Schedule Name + autosize, !- U-Factor Times Area Value {W/K} + autosize, !- Maximum Water Flow Rate {m3/s} + SPACE4-1 Zone Coil Water In Node, !- Water Inlet Node Name + SPACE4-1 Zone Coil Water Out Node, !- Water Outlet Node Name + SPACE4-1 Zone Coil Air In Node, !- Air Inlet Node Name + SPACE4-1 In Node, !- Air Outlet Node Name + UFactorTimesAreaAndDesignWaterFlowRate, !- Performance Input Method + autosize, !- Rated Capacity {W} + 82.2, !- Rated Inlet Water Temperature {C} + 16.6, !- Rated Inlet Air Temperature {C} + 71.1, !- Rated Outlet Water Temperature {C} + 32.2, !- Rated Outlet Air Temperature {C} + , !- Rated Ratio for Air and Water Convection + 11; !- Design Water Temperature Difference {deltaC} + + Coil:Heating:Water, + SPACE5-1 Zone Coil, !- Name + ReheatCoilAvailSched, !- Availability Schedule Name + autosize, !- U-Factor Times Area Value {W/K} + autosize, !- Maximum Water Flow Rate {m3/s} + SPACE5-1 Zone Coil Water In Node, !- Water Inlet Node Name + SPACE5-1 Zone Coil Water Out Node, !- Water Outlet Node Name + SPACE5-1 Zone Coil Air In Node, !- Air Inlet Node Name + SPACE5-1 In Node, !- Air Outlet Node Name + UFactorTimesAreaAndDesignWaterFlowRate, !- Performance Input Method + autosize, !- Rated Capacity {W} + 82.2, !- Rated Inlet Water Temperature {C} + 16.6, !- Rated Inlet Air Temperature {C} + 71.1, !- Rated Outlet Water Temperature {C} + 32.2, !- Rated Outlet Air Temperature {C} + , !- Rated Ratio for Air and Water Convection + 11; !- Design Water Temperature Difference {deltaC} + + AirLoopHVAC:ReturnPath, + ReturnAirPath1, !- Name + PLENUM-1 Out Node, !- Return Air Path Outlet Node Name + AirLoopHVAC:ReturnPlenum,!- Component 1 Object Type + Return-Plenum-1; !- Component 1 Name + + AirLoopHVAC:ReturnPlenum, + Return-Plenum-1, !- Name + PLENUM-1, !- Zone Name + PLENUM-1 Node, !- Zone Node Name + PLENUM-1 Out Node, !- Outlet Node Name + , !- Induced Air Outlet Node or NodeList Name + SPACE1-1 Out Node, !- Inlet 1 Node Name + SPACE2-1 Out Node, !- Inlet 2 Node Name + SPACE3-1 Out Node, !- Inlet 3 Node Name + SPACE4-1 Out Node, !- Inlet 4 Node Name + SPACE5-1 Out Node; !- Inlet 5 Node Name + + AirLoopHVAC:SupplyPath, + Zone Supply Air Path 1, !- Name + Zone Eq In Node, !- Supply Air Path Inlet Node Name + AirLoopHVAC:ZoneSplitter,!- Component 1 Object Type + Zone Supply Air Splitter 1; !- Component 1 Name + + AirLoopHVAC:ZoneSplitter, + Zone Supply Air Splitter 1, !- Name + Zone Eq In Node, !- Inlet Node Name + SPACE1-1 ATU In Node, !- Outlet 1 Node Name + SPACE2-1 ATU In Node, !- Outlet 2 Node Name + SPACE3-1 ATU In Node, !- Outlet 3 Node Name + SPACE4-1 ATU In Node, !- Outlet 4 Node Name + SPACE5-1 ATU In Node; !- Outlet 5 Node Name + + AirLoopHVAC, + VAV Sys 1, !- Name + VAV Sys 1 Controllers, !- Controller List Name + VAV Sys 1 Avail List, !- Availability Manager List Name + autosize, !- Design Supply Air Flow Rate {m3/s} + VAV Sys 1 Branches, !- Branch List Name + , !- Connector List Name + VAV Sys 1 Inlet Node, !- Supply Side Inlet Node Name + PLENUM-1 Out Node, !- Demand Side Outlet Node Name + Zone Eq In Node, !- Demand Side Inlet Node Names + VAV Sys 1 Outlet Node; !- Supply Side Outlet Node Names + + AirLoopHVAC:ControllerList, + VAV Sys 1 Controllers, !- Name + Controller:WaterCoil, !- Controller 1 Object Type + Central Cooling Coil Controller 1, !- Controller 1 Name + Controller:WaterCoil, !- Controller 2 Object Type + Central Heating Coil Controller 1; !- Controller 2 Name + + AvailabilityManagerAssignmentList, + VAV Sys 1 Avail List, !- Name + AvailabilityManager:Scheduled, !- Availability Manager 1 Object Type + VAV Sys 1 Avail; !- Availability Manager 1 Name + + AvailabilityManager:Scheduled, + VAV Sys 1 Avail, !- Name + FanAvailSched; !- Schedule Name + + BranchList, + VAV Sys 1 Branches, !- Name + VAV Sys 1 Main Branch; !- Branch 1 Name + + Branch, + VAV Sys 1 Main Branch, !- Name + , !- Pressure Drop Curve Name + AirLoopHVAC:OutdoorAirSystem, !- Component 1 Object Type + OA Sys 1, !- Component 1 Name + VAV Sys 1 Inlet Node, !- Component 1 Inlet Node Name + Mixed Air Node 1, !- Component 1 Outlet Node Name + Coil:Cooling:Water, !- Component 2 Object Type + Main Cooling Coil 1, !- Component 2 Name + Mixed Air Node 1, !- Component 2 Inlet Node Name + Main Cooling Coil 1 Outlet Node, !- Component 2 Outlet Node Name + Coil:Heating:Water, !- Component 3 Object Type + Main Heating Coil 1, !- Component 3 Name + Main Cooling Coil 1 Outlet Node, !- Component 3 Inlet Node Name + Main Heating Coil 1 Outlet Node, !- Component 3 Outlet Node Name + Fan:VariableVolume, !- Component 4 Object Type + Supply Fan 1, !- Component 4 Name + Main Heating Coil 1 Outlet Node, !- Component 4 Inlet Node Name + VAV Sys 1 Outlet Node; !- Component 4 Outlet Node Name + + AirLoopHVAC:OutdoorAirSystem, + OA Sys 1, !- Name + OA Sys 1 Controllers, !- Controller List Name + OA Sys 1 Equipment; !- Outdoor Air Equipment List Name + + AirLoopHVAC:ControllerList, + OA Sys 1 Controllers, !- Name + Controller:OutdoorAir, !- Controller 1 Object Type + OA Controller 1, !- Controller 1 Name + Controller:WaterCoil, !- Controller 2 Object Type + OA CC Controller 1, !- Controller 2 Name + Controller:WaterCoil, !- Controller 3 Object Type + OA HC Controller 1; !- Controller 3 Name + + AirLoopHVAC:OutdoorAirSystem:EquipmentList, + OA Sys 1 Equipment, !- Name + Coil:Heating:Water, !- Component 1 Object Type + OA Heating Coil 1, !- Component 1 Name + Coil:Cooling:Water, !- Component 2 Object Type + OA Cooling Coil 1, !- Component 2 Name + OutdoorAir:Mixer, !- Component 3 Object Type + OA Mixing Box 1; !- Component 3 Name + + Coil:Heating:Water, + OA Heating Coil 1, !- Name + CoolingCoilAvailSched, !- Availability Schedule Name + autosize, !- U-Factor Times Area Value {W/K} + autosize, !- Maximum Water Flow Rate {m3/s} + OA Heating Coil 1 Water Inlet Node, !- Water Inlet Node Name + OA Heating Coil 1 Water Outlet Node, !- Water Outlet Node Name + Outside Air Inlet Node 1,!- Air Inlet Node Name + OA Heating Coil 1 Air Outlet Node, !- Air Outlet Node Name + UFactorTimesAreaAndDesignWaterFlowRate, !- Performance Input Method + autosize, !- Rated Capacity {W} + 82.2, !- Rated Inlet Water Temperature {C} + 16.6, !- Rated Inlet Air Temperature {C} + 71.1, !- Rated Outlet Water Temperature {C} + 32.2, !- Rated Outlet Air Temperature {C} + , !- Rated Ratio for Air and Water Convection + 11; !- Design Water Temperature Difference {deltaC} + + Coil:Cooling:Water, + OA Cooling Coil 1, !- Name + CoolingCoilAvailSched, !- Availability Schedule Name + autosize, !- Design Water Flow Rate {m3/s} + autosize, !- Design Air Flow Rate {m3/s} + autosize, !- Design Inlet Water Temperature {C} + autosize, !- Design Inlet Air Temperature {C} + autosize, !- Design Outlet Air Temperature {C} + autosize, !- Design Inlet Air Humidity Ratio {kgWater/kgDryAir} + autosize, !- Design Outlet Air Humidity Ratio {kgWater/kgDryAir} + OA Cooling Coil 1 Water Inlet Node, !- Water Inlet Node Name + OA Cooling Coil 1 Water Outlet Node, !- Water Outlet Node Name + OA Heating Coil 1 Air Outlet Node, !- Air Inlet Node Name + OA Mixing Box 1 Inlet Node, !- Air Outlet Node Name + SimpleAnalysis, !- Type of Analysis + CrossFlow, !- Heat Exchanger Configuration + , !- Condensate Collection Water Storage Tank Name + 4.0; !- Design Water Temperature Difference {deltaC} + + OutdoorAir:Mixer, + OA Mixing Box 1, !- Name + Mixed Air Node 1, !- Mixed Air Node Name + OA Mixing Box 1 Inlet Node, !- Outdoor Air Stream Node Name + Relief Air Outlet Node 1,!- Relief Air Stream Node Name + VAV Sys 1 Inlet Node; !- Return Air Stream Node Name + + Coil:Cooling:Water, + Main Cooling Coil 1, !- Name + CoolingCoilAvailSched, !- Availability Schedule Name + autosize, !- Design Water Flow Rate {m3/s} + autosize, !- Design Air Flow Rate {m3/s} + autosize, !- Design Inlet Water Temperature {C} + autosize, !- Design Inlet Air Temperature {C} + autosize, !- Design Outlet Air Temperature {C} + autosize, !- Design Inlet Air Humidity Ratio {kgWater/kgDryAir} + autosize, !- Design Outlet Air Humidity Ratio {kgWater/kgDryAir} + Main Cooling Coil 1 Water Inlet Node, !- Water Inlet Node Name + Main Cooling Coil 1 Water Outlet Node, !- Water Outlet Node Name + Mixed Air Node 1, !- Air Inlet Node Name + Main Cooling Coil 1 Outlet Node, !- Air Outlet Node Name + SimpleAnalysis, !- Type of Analysis + CrossFlow, !- Heat Exchanger Configuration + , !- Condensate Collection Water Storage Tank Name + 4.0; !- Design Water Temperature Difference {deltaC} + + Coil:Heating:Water, + Main Heating Coil 1, !- Name + ReheatCoilAvailSched, !- Availability Schedule Name + autosize, !- U-Factor Times Area Value {W/K} + autosize, !- Maximum Water Flow Rate {m3/s} + Main Heating Coil 1 Water Inlet Node, !- Water Inlet Node Name + Main Heating Coil 1 Water Outlet Node, !- Water Outlet Node Name + Main Cooling Coil 1 Outlet Node, !- Air Inlet Node Name + Main Heating Coil 1 Outlet Node, !- Air Outlet Node Name + UFactorTimesAreaAndDesignWaterFlowRate, !- Performance Input Method + autosize, !- Rated Capacity {W} + 82.2, !- Rated Inlet Water Temperature {C} + 16.6, !- Rated Inlet Air Temperature {C} + 71.1, !- Rated Outlet Water Temperature {C} + 32.2, !- Rated Outlet Air Temperature {C} + , !- Rated Ratio for Air and Water Convection + 11; !- Design Water Temperature Difference {deltaC} + + Fan:VariableVolume, + Supply Fan 1, !- Name + FanAvailSched, !- Availability Schedule Name + 0.7, !- Fan Total Efficiency + 600.0, !- Pressure Rise {Pa} + autosize, !- Maximum Flow Rate {m3/s} + Fraction, !- Fan Power Minimum Flow Rate Input Method + 0.25, !- Fan Power Minimum Flow Fraction + , !- Fan Power Minimum Air Flow Rate {m3/s} + 0.9, !- Motor Efficiency + 1.0, !- Motor In Airstream Fraction + 0.35071223, !- Fan Power Coefficient 1 + 0.30850535, !- Fan Power Coefficient 2 + -0.54137364, !- Fan Power Coefficient 3 + 0.87198823, !- Fan Power Coefficient 4 + 0.000, !- Fan Power Coefficient 5 + Main Heating Coil 1 Outlet Node, !- Air Inlet Node Name + VAV Sys 1 Outlet Node; !- Air Outlet Node Name + + Controller:WaterCoil, + OA HC Controller 1, !- Name + Temperature, !- Control Variable + Normal, !- Action + FLOW, !- Actuator Variable + OA Heating Coil 1 Air Outlet Node, !- Sensor Node Name + OA Heating Coil 1 Water Inlet Node, !- Actuator Node Name + 0.002, !- Controller Convergence Tolerance {deltaC} + autosize, !- Maximum Actuated Flow {m3/s} + 0.0; !- Minimum Actuated Flow {m3/s} + + Controller:WaterCoil, + OA CC Controller 1, !- Name + Temperature, !- Control Variable + Reverse, !- Action + FLOW, !- Actuator Variable + OA Mixing Box 1 Inlet Node, !- Sensor Node Name + OA Cooling Coil 1 Water Inlet Node, !- Actuator Node Name + 0.002, !- Controller Convergence Tolerance {deltaC} + autosize, !- Maximum Actuated Flow {m3/s} + 0.0; !- Minimum Actuated Flow {m3/s} + + Controller:WaterCoil, + Central Cooling Coil Controller 1, !- Name + Temperature, !- Control Variable + Reverse, !- Action + FLOW, !- Actuator Variable + Main Cooling Coil 1 Outlet Node, !- Sensor Node Name + Main Cooling Coil 1 Water Inlet Node, !- Actuator Node Name + 0.002, !- Controller Convergence Tolerance {deltaC} + autosize, !- Maximum Actuated Flow {m3/s} + 0.0; !- Minimum Actuated Flow {m3/s} + + Controller:OutdoorAir, + OA Controller 1, !- Name + Relief Air Outlet Node 1,!- Relief Air Outlet Node Name + VAV Sys 1 Inlet Node, !- Return Air Node Name + Mixed Air Node 1, !- Mixed Air Node Name + Outside Air Inlet Node 1,!- Actuator Node Name + autosize, !- Minimum Outdoor Air Flow Rate {m3/s} + autosize, !- Maximum Outdoor Air Flow Rate {m3/s} + NoEconomizer, !- Economizer Control Type + ModulateFlow, !- Economizer Control Action Type + 19., !- Economizer Maximum Limit Dry-Bulb Temperature {C} + , !- Economizer Maximum Limit Enthalpy {J/kg} + , !- Economizer Maximum Limit Dewpoint Temperature {C} + , !- Electronic Enthalpy Limit Curve Name + 4.6, !- Economizer Minimum Limit Dry-Bulb Temperature {C} + NoLockout, !- Lockout Type + FixedMinimum, !- Minimum Limit Type + Min OA Sched; !- Minimum Outdoor Air Schedule Name + + Controller:WaterCoil, + Central Heating Coil Controller 1, !- Name + Temperature, !- Control Variable + Normal, !- Action + FLOW, !- Actuator Variable + Main Heating Coil 1 Outlet Node, !- Sensor Node Name + Main Heating Coil 1 Water Inlet Node, !- Actuator Node Name + 0.002, !- Controller Convergence Tolerance {deltaC} + autosize, !- Maximum Actuated Flow {m3/s} + 0.0; !- Minimum Actuated Flow {m3/s} + + SetpointManager:Scheduled, + Supply Air Temp Manager 1, !- Name + Temperature, !- Control Variable + Seasonal Reset Supply Air Temp Sch, !- Schedule Name + VAV Sys 1 Outlet Node; !- Setpoint Node or NodeList Name + + SetpointManager:Scheduled, + OA Air Temp Manager 1, !- Name + Temperature, !- Control Variable + OA Cooling Supply Air Temp Sch, !- Schedule Name + OA Mixing Box 1 Inlet Node; !- Setpoint Node or NodeList Name + + SetpointManager:Scheduled, + OA Air Temp Manager 2, !- Name + Temperature, !- Control Variable + OA Heating Supply Air Temp Sch, !- Schedule Name + OA Heating Coil 1 Air Outlet Node; !- Setpoint Node or NodeList Name + + SetpointManager:MixedAir, + Mixed Air Temp Manager 1,!- Name + Temperature, !- Control Variable + VAV Sys 1 Outlet Node, !- Reference Setpoint Node Name + Main Heating Coil 1 Outlet Node, !- Fan Inlet Node Name + VAV Sys 1 Outlet Node, !- Fan Outlet Node Name + Main Branch SetPoint Node List; !- Setpoint Node or NodeList Name + + NodeList, + Main Branch SetPoint Node List, !- Name + Mixed Air Node 1, !- Node 1 Name + Main Cooling Coil 1 Outlet Node, !- Node 2 Name + Main Heating Coil 1 Outlet Node; !- Node 3 Name + + PlantLoop, + Hot Water Loop, !- Name + Water, !- Fluid Type + , !- User Defined Fluid Type + Hot Loop Operation, !- Plant Equipment Operation Scheme Name + HW Supply Outlet Node, !- Loop Temperature Setpoint Node Name + 100, !- Maximum Loop Temperature {C} + 10, !- Minimum Loop Temperature {C} + autosize, !- Maximum Loop Flow Rate {m3/s} + 0.0, !- Minimum Loop Flow Rate {m3/s} + , !- Plant Loop Volume {m3} + HW Supply Inlet Node, !- Plant Side Inlet Node Name + HW Supply Outlet Node, !- Plant Side Outlet Node Name + Heating Supply Side Branches, !- Plant Side Branch List Name + Heating Supply Side Connectors, !- Plant Side Connector List Name + HW Demand Inlet Node, !- Demand Side Inlet Node Name + HW Demand Outlet Node, !- Demand Side Outlet Node Name + Heating Demand Side Branches, !- Demand Side Branch List Name + Heating Demand Side Connectors, !- Demand Side Connector List Name + SequentialLoad; !- Load Distribution Scheme + + SetpointManager:Scheduled, + Hot Water Loop Setpoint Manager, !- Name + Temperature, !- Control Variable + HW Loop Temp Schedule, !- Schedule Name + HW Supply Outlet Node; !- Setpoint Node or NodeList Name + + BranchList, + Heating Supply Side Branches, !- Name + Heating Supply Inlet Branch, !- Branch 1 Name + Central Boiler Branch, !- Branch 2 Name + Heating Supply Bypass Branch, !- Branch 3 Name + Heating Supply Outlet Branch; !- Branch 4 Name + + ConnectorList, + Heating Supply Side Connectors, !- Name + Connector:Splitter, !- Connector 1 Object Type + Heating Supply Splitter, !- Connector 1 Name + Connector:Mixer, !- Connector 2 Object Type + Heating Supply Mixer; !- Connector 2 Name + + Branch, + Heating Supply Inlet Branch, !- Name + , !- Pressure Drop Curve Name + Pump:VariableSpeed, !- Component 1 Object Type + HW Circ Pump, !- Component 1 Name + HW Supply Inlet Node, !- Component 1 Inlet Node Name + HW Pump Outlet Node; !- Component 1 Outlet Node Name + + Branch, + Central Boiler Branch, !- Name + , !- Pressure Drop Curve Name + Boiler:HotWater, !- Component 1 Object Type + Central Boiler, !- Component 1 Name + Central Boiler Inlet Node, !- Component 1 Inlet Node Name + Central Boiler Outlet Node; !- Component 1 Outlet Node Name + + Branch, + Heating Supply Bypass Branch, !- Name + , !- Pressure Drop Curve Name + Pipe:Adiabatic, !- Component 1 Object Type + Heating Supply Side Bypass, !- Component 1 Name + Heating Supply Bypass Inlet Node, !- Component 1 Inlet Node Name + Heating Supply Bypass Outlet Node; !- Component 1 Outlet Node Name + + Pipe:Adiabatic, + Heating Supply Side Bypass, !- Name + Heating Supply Bypass Inlet Node, !- Inlet Node Name + Heating Supply Bypass Outlet Node; !- Outlet Node Name + + Branch, + Heating Supply Outlet Branch, !- Name + , !- Pressure Drop Curve Name + Pipe:Adiabatic, !- Component 1 Object Type + Heating Supply Outlet, !- Component 1 Name + Heating Supply Exit Pipe Inlet Node, !- Component 1 Inlet Node Name + HW Supply Outlet Node; !- Component 1 Outlet Node Name + + Pipe:Adiabatic, + Heating Supply Outlet, !- Name + Heating Supply Exit Pipe Inlet Node, !- Inlet Node Name + HW Supply Outlet Node; !- Outlet Node Name + + BranchList, + Heating Demand Side Branches, !- Name + Heating Demand Inlet Branch, !- Branch 1 Name + SPACE1-1 Reheat Branch, !- Branch 2 Name + SPACE2-1 Reheat Branch, !- Branch 3 Name + SPACE3-1 Reheat Branch, !- Branch 4 Name + SPACE4-1 Reheat Branch, !- Branch 5 Name + SPACE5-1 Reheat Branch, !- Branch 6 Name + OA Heating Coil Branch, !- Branch 7 Name + Main Heating Coil 1 Branch, !- Branch 8 Name + Heating Demand Bypass Branch, !- Branch 9 Name + Heating Demand Outlet Branch; !- Branch 10 Name + + ConnectorList, + Heating Demand Side Connectors, !- Name + Connector:Splitter, !- Connector 1 Object Type + Heating Demand Splitter, !- Connector 1 Name + Connector:Mixer, !- Connector 2 Object Type + Heating Demand Mixer; !- Connector 2 Name + + Branch, + Heating Demand Inlet Branch, !- Name + , !- Pressure Drop Curve Name + Pipe:Adiabatic, !- Component 1 Object Type + Heating Demand Inlet Pipe, !- Component 1 Name + HW Demand Inlet Node, !- Component 1 Inlet Node Name + HW Demand Entrance Pipe Outlet Node; !- Component 1 Outlet Node Name + + Pipe:Adiabatic, + Heating Demand Inlet Pipe, !- Name + HW Demand Inlet Node, !- Inlet Node Name + HW Demand Entrance Pipe Outlet Node; !- Outlet Node Name + + Branch, + Heating Demand Outlet Branch, !- Name + , !- Pressure Drop Curve Name + Pipe:Adiabatic, !- Component 1 Object Type + Heating Demand Outlet Pipe, !- Component 1 Name + HW Demand Exit Pipe Inlet Node, !- Component 1 Inlet Node Name + HW Demand Outlet Node; !- Component 1 Outlet Node Name + + Pipe:Adiabatic, + Heating Demand Outlet Pipe, !- Name + HW Demand Exit Pipe Inlet Node, !- Inlet Node Name + HW Demand Outlet Node; !- Outlet Node Name + + Branch, + SPACE1-1 Reheat Branch, !- Name + , !- Pressure Drop Curve Name + Coil:Heating:Water, !- Component 1 Object Type + SPACE1-1 Zone Coil, !- Component 1 Name + SPACE1-1 Zone Coil Water In Node, !- Component 1 Inlet Node Name + SPACE1-1 Zone Coil Water Out Node; !- Component 1 Outlet Node Name + + Branch, + SPACE2-1 Reheat Branch, !- Name + , !- Pressure Drop Curve Name + Coil:Heating:Water, !- Component 1 Object Type + SPACE2-1 Zone Coil, !- Component 1 Name + SPACE2-1 Zone Coil Water In Node, !- Component 1 Inlet Node Name + SPACE2-1 Zone Coil Water Out Node; !- Component 1 Outlet Node Name + + Branch, + SPACE3-1 Reheat Branch, !- Name + , !- Pressure Drop Curve Name + Coil:Heating:Water, !- Component 1 Object Type + SPACE3-1 Zone Coil, !- Component 1 Name + SPACE3-1 Zone Coil Water In Node, !- Component 1 Inlet Node Name + SPACE3-1 Zone Coil Water Out Node; !- Component 1 Outlet Node Name + + Branch, + SPACE4-1 Reheat Branch, !- Name + , !- Pressure Drop Curve Name + Coil:Heating:Water, !- Component 1 Object Type + SPACE4-1 Zone Coil, !- Component 1 Name + SPACE4-1 Zone Coil Water In Node, !- Component 1 Inlet Node Name + SPACE4-1 Zone Coil Water Out Node; !- Component 1 Outlet Node Name + + Branch, + SPACE5-1 Reheat Branch, !- Name + , !- Pressure Drop Curve Name + Coil:Heating:Water, !- Component 1 Object Type + SPACE5-1 Zone Coil, !- Component 1 Name + SPACE5-1 Zone Coil Water In Node, !- Component 1 Inlet Node Name + SPACE5-1 Zone Coil Water Out Node; !- Component 1 Outlet Node Name + + Branch, + OA Heating Coil Branch, !- Name + , !- Pressure Drop Curve Name + Coil:Heating:Water, !- Component 1 Object Type + OA Heating Coil 1, !- Component 1 Name + OA Heating Coil 1 Water Inlet Node, !- Component 1 Inlet Node Name + OA Heating Coil 1 Water Outlet Node; !- Component 1 Outlet Node Name + + Branch, + Main Heating Coil 1 Branch, !- Name + , !- Pressure Drop Curve Name + Coil:Heating:Water, !- Component 1 Object Type + Main Heating Coil 1, !- Component 1 Name + Main Heating Coil 1 Water Inlet Node, !- Component 1 Inlet Node Name + Main Heating Coil 1 Water Outlet Node; !- Component 1 Outlet Node Name + + Branch, + Heating Demand Bypass Branch, !- Name + , !- Pressure Drop Curve Name + Pipe:Adiabatic, !- Component 1 Object Type + Heating Demand Bypass, !- Component 1 Name + Heating Demand Bypass Inlet Node, !- Component 1 Inlet Node Name + Heating Demand Bypass Outlet Node; !- Component 1 Outlet Node Name + + Pipe:Adiabatic, + Heating Demand Bypass, !- Name + Heating Demand Bypass Inlet Node, !- Inlet Node Name + Heating Demand Bypass Outlet Node; !- Outlet Node Name + + Connector:Splitter, + Heating Demand Splitter, !- Name + Heating Demand Inlet Branch, !- Inlet Branch Name + SPACE1-1 Reheat Branch, !- Outlet Branch 1 Name + SPACE2-1 Reheat Branch, !- Outlet Branch 2 Name + SPACE3-1 Reheat Branch, !- Outlet Branch 3 Name + SPACE4-1 Reheat Branch, !- Outlet Branch 4 Name + SPACE5-1 Reheat Branch, !- Outlet Branch 5 Name + OA Heating Coil Branch, !- Outlet Branch 6 Name + Main Heating Coil 1 Branch, !- Outlet Branch 7 Name + Heating Demand Bypass Branch; !- Outlet Branch 8 Name + + Connector:Mixer, + Heating Demand Mixer, !- Name + Heating Demand Outlet Branch, !- Outlet Branch Name + SPACE1-1 Reheat Branch, !- Inlet Branch 1 Name + SPACE2-1 Reheat Branch, !- Inlet Branch 2 Name + SPACE3-1 Reheat Branch, !- Inlet Branch 3 Name + SPACE4-1 Reheat Branch, !- Inlet Branch 4 Name + SPACE5-1 Reheat Branch, !- Inlet Branch 5 Name + OA Heating Coil Branch, !- Inlet Branch 6 Name + Main Heating Coil 1 Branch, !- Inlet Branch 7 Name + Heating Demand Bypass Branch; !- Inlet Branch 8 Name + + Connector:Splitter, + Heating Supply Splitter, !- Name + Heating Supply Inlet Branch, !- Inlet Branch Name + Central Boiler Branch, !- Outlet Branch 1 Name + Heating Supply Bypass Branch; !- Outlet Branch 2 Name + + Connector:Mixer, + Heating Supply Mixer, !- Name + Heating Supply Outlet Branch, !- Outlet Branch Name + Central Boiler Branch, !- Inlet Branch 1 Name + Heating Supply Bypass Branch; !- Inlet Branch 2 Name + + PlantEquipmentOperationSchemes, + Hot Loop Operation, !- Name + PlantEquipmentOperation:HeatingLoad, !- Control Scheme 1 Object Type + Central Boiler Only, !- Control Scheme 1 Name + PlantOnSched; !- Control Scheme 1 Schedule Name + + PlantEquipmentOperation:HeatingLoad, + Central Boiler Only, !- Name + 0, !- Load Range 1 Lower Limit {W} + 1000000, !- Load Range 1 Upper Limit {W} + heating plant; !- Range 1 Equipment List Name + + PlantEquipmentList, + heating plant, !- Name + Boiler:HotWater, !- Equipment 1 Object Type + Central Boiler; !- Equipment 1 Name + + Boiler:HotWater, + Central Boiler, !- Name + NaturalGas, !- Fuel Type + autosize, !- Nominal Capacity {W} + 0.8, !- Nominal Thermal Efficiency + LeavingBoiler, !- Efficiency Curve Temperature Evaluation Variable + BoilerEfficiency, !- Normalized Boiler Efficiency Curve Name + autosize, !- Design Water Flow Rate {m3/s} + 0.0, !- Minimum Part Load Ratio + 1.2, !- Maximum Part Load Ratio + 1.0, !- Optimum Part Load Ratio + Central Boiler Inlet Node, !- Boiler Water Inlet Node Name + Central Boiler Outlet Node, !- Boiler Water Outlet Node Name + 100., !- Water Outlet Upper Temperature Limit {C} + LeavingSetpointModulated;!- Boiler Flow Mode + + SetpointManager:Scheduled, + Central Boiler Setpoint Manager, !- Name + Temperature, !- Control Variable + HW Loop Temp Schedule, !- Schedule Name + Central Boiler Outlet Node; !- Setpoint Node or NodeList Name + + Curve:Quadratic, + BoilerEfficiency, !- Name + 1.0, !- Coefficient1 Constant + 0.0, !- Coefficient2 x + 0.0, !- Coefficient3 x**2 + 0, !- Minimum Value of x + 1; !- Maximum Value of x + + Pump:VariableSpeed, + HW Circ Pump, !- Name + HW Supply Inlet Node, !- Inlet Node Name + HW Pump Outlet Node, !- Outlet Node Name + autosize, !- Design Maximum Flow Rate {m3/s} + 179352, !- Design Pump Head {Pa} + autosize, !- Design Power Consumption {W} + 0.9, !- Motor Efficiency + 0.0, !- Fraction of Motor Inefficiencies to Fluid Stream + 0, !- Coefficient 1 of the Part Load Performance Curve + 1, !- Coefficient 2 of the Part Load Performance Curve + 0, !- Coefficient 3 of the Part Load Performance Curve + 0, !- Coefficient 4 of the Part Load Performance Curve + 0, !- Design Minimum Flow Rate {m3/s} + INTERMITTENT; !- Pump Control Type + + PlantLoop, + Chilled Water Loop, !- Name + Water, !- Fluid Type + , !- User Defined Fluid Type + CW Loop Operation, !- Plant Equipment Operation Scheme Name + CW Supply Outlet Node, !- Loop Temperature Setpoint Node Name + 98, !- Maximum Loop Temperature {C} + 1, !- Minimum Loop Temperature {C} + autosize, !- Maximum Loop Flow Rate {m3/s} + 0.0, !- Minimum Loop Flow Rate {m3/s} + , !- Plant Loop Volume {m3} + CW Supply Inlet Node, !- Plant Side Inlet Node Name + CW Supply Outlet Node, !- Plant Side Outlet Node Name + Cooling Supply Side Branches, !- Plant Side Branch List Name + Cooling Supply Side Connectors, !- Plant Side Connector List Name + CW Demand Inlet Node, !- Demand Side Inlet Node Name + CW Demand Outlet Node, !- Demand Side Outlet Node Name + Cooling Demand Side Branches, !- Demand Side Branch List Name + Cooling Demand Side Connectors, !- Demand Side Connector List Name + SequentialLoad, !- Load Distribution Scheme + CW Avail List; !- Availability Manager List Name + + AvailabilityManagerAssignmentList, + CW Avail List, !- Name + AvailabilityManager:LowTemperatureTurnOff, !- Availability Manager 1 Object Type + CW Low Temp Limit; !- Availability Manager 1 Name + + AvailabilityManager:LowTemperatureTurnOff, + CW Low Temp Limit, !- Name + Outside Air Inlet Node 1,!- Sensor Node Name + 2.0, !- Temperature {C} + CoolingPumpAvailSched; !- Applicability Schedule Name + + SetpointManager:Scheduled, + Chilled Water Loop Setpoint Manager, !- Name + Temperature, !- Control Variable + CW Loop Temp Schedule, !- Schedule Name + CW Supply Outlet Node; !- Setpoint Node or NodeList Name + + BranchList, + Cooling Supply Side Branches, !- Name + CW Pump Branch, !- Branch 1 Name + Central Chiller Branch, !- Branch 2 Name + Cooling Supply Bypass Branch, !- Branch 3 Name + Cooling Supply Outlet; !- Branch 4 Name + + BranchList, + Cooling Demand Side Branches, !- Name + Cooling Demand Inlet, !- Branch 1 Name + Cooling Coil Branch, !- Branch 2 Name + OA Cooling Coil Branch, !- Branch 3 Name + Cooling Demand Bypass Branch, !- Branch 4 Name + Cooling Demand Outlet; !- Branch 5 Name + + ConnectorList, + Cooling Supply Side Connectors, !- Name + Connector:Splitter, !- Connector 1 Object Type + CW Loop Splitter, !- Connector 1 Name + Connector:Mixer, !- Connector 2 Object Type + CW Loop Mixer; !- Connector 2 Name + + ConnectorList, + Cooling Demand Side Connectors, !- Name + Connector:Splitter, !- Connector 1 Object Type + CW Demand Splitter, !- Connector 1 Name + Connector:Mixer, !- Connector 2 Object Type + CW Demand Mixer; !- Connector 2 Name + + Branch, + Cooling Demand Inlet, !- Name + , !- Pressure Drop Curve Name + Pipe:Adiabatic, !- Component 1 Object Type + Cooling Demand Side Inlet Pipe, !- Component 1 Name + CW Demand Inlet Node, !- Component 1 Inlet Node Name + CW Demand Entrance Pipe Outlet Node; !- Component 1 Outlet Node Name + + Pipe:Adiabatic, + Cooling Demand Side Inlet Pipe, !- Name + CW Demand Inlet Node, !- Inlet Node Name + CW Demand Entrance Pipe Outlet Node; !- Outlet Node Name + + Branch, + Cooling Coil Branch, !- Name + , !- Pressure Drop Curve Name + Coil:Cooling:Water, !- Component 1 Object Type + Main Cooling Coil 1, !- Component 1 Name + Main Cooling Coil 1 Water Inlet Node, !- Component 1 Inlet Node Name + Main Cooling Coil 1 Water Outlet Node; !- Component 1 Outlet Node Name + + Branch, + OA Cooling Coil Branch, !- Name + , !- Pressure Drop Curve Name + Coil:Cooling:Water, !- Component 1 Object Type + OA Cooling Coil 1, !- Component 1 Name + OA Cooling Coil 1 Water Inlet Node, !- Component 1 Inlet Node Name + OA Cooling Coil 1 Water Outlet Node; !- Component 1 Outlet Node Name + + Branch, + Cooling Demand Bypass Branch, !- Name + , !- Pressure Drop Curve Name + Pipe:Adiabatic, !- Component 1 Object Type + Cooling Demand Side Bypass, !- Component 1 Name + CW Demand Bypass Inlet Node, !- Component 1 Inlet Node Name + CW Demand Bypass Outlet Node; !- Component 1 Outlet Node Name + + Pipe:Adiabatic, + Cooling Demand Side Bypass, !- Name + CW Demand Bypass Inlet Node, !- Inlet Node Name + CW Demand Bypass Outlet Node; !- Outlet Node Name + + Branch, + Cooling Demand Outlet, !- Name + , !- Pressure Drop Curve Name + Pipe:Adiabatic, !- Component 1 Object Type + CW Demand Side Outlet Pipe, !- Component 1 Name + CW Demand Exit Pipe Inlet Node, !- Component 1 Inlet Node Name + CW Demand Outlet Node; !- Component 1 Outlet Node Name + + Pipe:Adiabatic, + CW Demand Side Outlet Pipe, !- Name + CW Demand Exit Pipe Inlet Node, !- Inlet Node Name + CW Demand Outlet Node; !- Outlet Node Name + + Branch, + Cooling Supply Outlet, !- Name + , !- Pressure Drop Curve Name + Pipe:Adiabatic, !- Component 1 Object Type + Supply Side Outlet Pipe, !- Component 1 Name + Supply Side Exit Pipe Inlet Node, !- Component 1 Inlet Node Name + CW Supply Outlet Node; !- Component 1 Outlet Node Name + + Pipe:Adiabatic, + Supply Side Outlet Pipe, !- Name + Supply Side Exit Pipe Inlet Node, !- Inlet Node Name + CW Supply Outlet Node; !- Outlet Node Name + + Branch, + CW Pump Branch, !- Name + , !- Pressure Drop Curve Name + Pump:VariableSpeed, !- Component 1 Object Type + CW Circ Pump, !- Component 1 Name + CW Supply Inlet Node, !- Component 1 Inlet Node Name + CW Pump Outlet Node; !- Component 1 Outlet Node Name + + Branch, + Central Chiller Branch, !- Name + , !- Pressure Drop Curve Name + Chiller:Electric, !- Component 1 Object Type + Central Chiller, !- Component 1 Name + Central Chiller Inlet Node, !- Component 1 Inlet Node Name + Central Chiller Outlet Node; !- Component 1 Outlet Node Name + + Branch, + Cooling Supply Bypass Branch, !- Name + , !- Pressure Drop Curve Name + Pipe:Adiabatic, !- Component 1 Object Type + Supply Side Bypass, !- Component 1 Name + CW Supply Bypass Inlet Node, !- Component 1 Inlet Node Name + CW Supply Bypass Outlet Node; !- Component 1 Outlet Node Name + + Pipe:Adiabatic, + Supply Side Bypass, !- Name + CW Supply Bypass Inlet Node, !- Inlet Node Name + CW Supply Bypass Outlet Node; !- Outlet Node Name + + Connector:Splitter, + CW Loop Splitter, !- Name + CW Pump Branch, !- Inlet Branch Name + Central Chiller Branch, !- Outlet Branch 1 Name + Cooling Supply Bypass Branch; !- Outlet Branch 2 Name + + Connector:Mixer, + CW Loop Mixer, !- Name + Cooling Supply Outlet, !- Outlet Branch Name + Central Chiller Branch, !- Inlet Branch 1 Name + Cooling Supply Bypass Branch; !- Inlet Branch 2 Name + + Connector:Splitter, + CW Demand Splitter, !- Name + Cooling Demand Inlet, !- Inlet Branch Name + Cooling Coil Branch, !- Outlet Branch 1 Name + OA Cooling Coil Branch, !- Outlet Branch 2 Name + Cooling Demand Bypass Branch; !- Outlet Branch 3 Name + + Connector:Mixer, + CW Demand Mixer, !- Name + Cooling Demand Outlet, !- Outlet Branch Name + Cooling Coil Branch, !- Inlet Branch 1 Name + OA Cooling Coil Branch, !- Inlet Branch 2 Name + Cooling Demand Bypass Branch; !- Inlet Branch 3 Name + + PlantEquipmentOperationSchemes, + CW Loop Operation, !- Name + PlantEquipmentOperation:CoolingLoad, !- Control Scheme 1 Object Type + Central Chiller Only, !- Control Scheme 1 Name + PlantOnSched; !- Control Scheme 1 Schedule Name + + PlantEquipmentOperation:CoolingLoad, + Central Chiller Only, !- Name + 0, !- Load Range 1 Lower Limit {W} + 900000, !- Load Range 1 Upper Limit {W} + Cooling Plant; !- Range 1 Equipment List Name + + PlantEquipmentList, + Cooling Plant, !- Name + Chiller:Electric, !- Equipment 1 Object Type + Central Chiller; !- Equipment 1 Name + + Chiller:Electric, + Central Chiller, !- Name + AirCooled, !- Condenser Type + autosize, !- Nominal Capacity {W} + 3.2, !- Nominal COP {W/W} + Central Chiller Inlet Node, !- Chilled Water Inlet Node Name + Central Chiller Outlet Node, !- Chilled Water Outlet Node Name + Central Chiller Condenser Inlet Node, !- Condenser Inlet Node Name + Central Chiller Condenser Outlet Node, !- Condenser Outlet Node Name + 0.0, !- Minimum Part Load Ratio + 1.0, !- Maximum Part Load Ratio + 0.65, !- Optimum Part Load Ratio + 35.0, !- Design Condenser Inlet Temperature {C} + 2.778, !- Temperature Rise Coefficient + 6.67, !- Design Chilled Water Outlet Temperature {C} + autosize, !- Design Chilled Water Flow Rate {m3/s} + autosize, !- Design Condenser Fluid Flow Rate {m3/s} + 0.9949, !- Coefficient 1 of Capacity Ratio Curve + -0.045954, !- Coefficient 2 of Capacity Ratio Curve + -0.0013543, !- Coefficient 3 of Capacity Ratio Curve + 2.333, !- Coefficient 1 of Power Ratio Curve + -1.975, !- Coefficient 2 of Power Ratio Curve + 0.6121, !- Coefficient 3 of Power Ratio Curve + 0.03303, !- Coefficient 1 of Full Load Ratio Curve + 0.6852, !- Coefficient 2 of Full Load Ratio Curve + 0.2818, !- Coefficient 3 of Full Load Ratio Curve + 5, !- Chilled Water Outlet Temperature Lower Limit {C} + LeavingSetpointModulated;!- Chiller Flow Mode + + SetpointManager:Scheduled, + Central Chiller Setpoint Manager, !- Name + Temperature, !- Control Variable + CW Loop Temp Schedule, !- Schedule Name + Central Chiller Outlet Node; !- Setpoint Node or NodeList Name + + OutdoorAir:Node, + Central Chiller Condenser Inlet Node, !- Name + -1.0; !- Height Above Ground {m} + + Pump:VariableSpeed, + CW Circ Pump, !- Name + CW Supply Inlet Node, !- Inlet Node Name + CW Pump Outlet Node, !- Outlet Node Name + autosize, !- Design Maximum Flow Rate {m3/s} + 179352, !- Design Pump Head {Pa} + autosize, !- Design Power Consumption {W} + 0.9, !- Motor Efficiency + 0.0, !- Fraction of Motor Inefficiencies to Fluid Stream + 0, !- Coefficient 1 of the Part Load Performance Curve + 1, !- Coefficient 2 of the Part Load Performance Curve + 0, !- Coefficient 3 of the Part Load Performance Curve + 0, !- Coefficient 4 of the Part Load Performance Curve + 0, !- Design Minimum Flow Rate {m3/s} + INTERMITTENT, !- Pump Control Type + CoolingPumpAvailSched; !- Pump Flow Rate Schedule Name + + Output:Variable,*,Site Outdoor Air Drybulb Temperature,hourly; + + Output:Variable,*,Zone Air Temperature,hourly; + + Output:Variable,*,Zone Mean Air Dewpoint Temperature,hourly; + + Output:Variable,*,Space Air Temperature,hourly; + + Output:Variable,*,Space Mean Air Dewpoint Temperature,hourly; + + Output:Variable,*,Zone Air System Sensible Cooling Rate,hourly; + + Output:Variable,*,Zone Air System Sensible Heating Rate,hourly; + + Output:Variable,OA Mixing Box 1 Inlet Node,System Node Temperature,hourly; + + Output:Variable,OA Mixing Box 1 Inlet Node,System Node Mass Flow Rate,hourly; + + Output:Variable,OA Mixing Box 1 Inlet Node,System Node Setpoint Temperature,hourly; + + Output:Variable,OA Mixing Box 1 Inlet Node,System Node Humidity Ratio,hourly; + + Output:Variable,OA Heating Coil 1 Air Outlet Node,System Node Temperature,hourly; + + Output:Variable,OA Heating Coil 1 Air Outlet Node,System Node Mass Flow Rate,hourly; + + Output:Variable,OA Heating Coil 1 Air Outlet Node,System Node Setpoint Temperature,hourly; + + Output:Variable,OA Heating Coil 1 Air Outlet Node,System Node Humidity Ratio,hourly; + + Output:Variable,Mixed Air Node 1,System Node Temperature,hourly; + + Output:Variable,Mixed Air Node 1,System Node Humidity Ratio,hourly; + + Output:Variable,Mixed Air Node 1,System Node Dewpoint Temperature,hourly; + + Output:Variable,VAV Sys 1 Outlet Node,System Node Temperature,hourly; + + Output:Variable,VAV Sys 1 Outlet Node,System Node Mass Flow Rate,hourly; + + Output:Variable,VAV Sys 1 Outlet Node,System Node Humidity Ratio,hourly; + + Output:Variable,VAV Sys 1 Outlet Node,System Node Setpoint Temperature,hourly; + + Output:Variable,OA Cooling Coil 1 Water Inlet Node,System Node Temperature,hourly; + + Output:Variable,OA Cooling Coil 1 Water Inlet Node,System Node Mass Flow Rate,hourly; + + Output:Variable,Main Cooling Coil 1 Water Inlet Node,System Node Mass Flow Rate,hourly; + + Output:Variable,OA Heating Coil 1 Water Inlet Node,System Node Temperature,hourly; + + Output:Variable,OA Heating Coil 1 Water Inlet Node,System Node Mass Flow Rate,hourly; + + Output:Variable,Main Heating Coil 1 Water Inlet Node,System Node Mass Flow Rate,hourly; + + Output:Variable,*,Heating Coil Heating Rate,hourly; + + Output:Variable,*,Cooling Coil Total Cooling Rate,hourly; + + Output:Variable,*,Cooling Coil Sensible Cooling Rate,hourly; + + Output:Variable,*,Plant Supply Side Cooling Demand Rate,hourly; + + Output:Variable,*,Plant Supply Side Heating Demand Rate,hourly; + + Output:Variable,*,Boiler NaturalGas Rate,hourly; + + Output:Variable,*,Boiler Heating Rate,hourly; + + Output:Variable,*,Chiller Electricity Rate,hourly; + + Output:Variable,*,Chiller Evaporator Cooling Rate,hourly; + + Output:Variable,*,Chiller Evaporator Inlet Temperature,hourly; + + Output:Variable,*,Chiller Evaporator Outlet Temperature,hourly; + + Output:Variable,*,Chiller Evaporator Mass Flow Rate,hourly; + + Output:Variable,*,Chiller Condenser Heat Transfer Rate,hourly; + + Output:Variable,*,Pump Mass Flow Rate,hourly; + + Output:Variable,*,Pump Outlet Temperature,hourly; + + Output:Variable,*,Zone Air Heat Balance Surface Convection Rate,hourly; !- HVAC Average [W] + Output:Variable,*,Zone Air Heat Balance Interzone Air Transfer Rate,hourly; !- HVAC Average [W] + Output:Variable,*,Zone Air Heat Balance Outdoor Air Transfer Rate,hourly; !- HVAC Average [W] + Output:Variable,*,Zone Air Heat Balance System Air Transfer Rate,hourly; !- HVAC Average [W] + Output:Variable,*,Zone Air Heat Balance System Convective Heat Gain Rate,hourly; !- HVAC Average [W] + Output:Variable,*,Zone Air Heat Balance Air Energy Storage Rate,hourly; !- HVAC Average [W] + + Output:Variable,*,Space Air Heat Balance Internal Convective Heat Gain Rate,hourly; !- HVAC Average [W] + Output:Variable,*,Space Air Heat Balance Surface Convection Rate,hourly; !- HVAC Average [W] + Output:Variable,*,Space Air Heat Balance Interzone Air Transfer Rate,hourly; !- HVAC Average [W] + Output:Variable,*,Space Air Heat Balance Outdoor Air Transfer Rate,hourly; !- HVAC Average [W] + Output:Variable,*,Space Air Heat Balance System Air Transfer Rate,hourly; !- HVAC Average [W] + Output:Variable,*,Space Air Heat Balance System Convective Heat Gain Rate,hourly; !- HVAC Average [W] + Output:Variable,*,Space Air Heat Balance Air Energy Storage Rate,hourly; !- HVAC Average [W] + + Output:Variable,*,Zone Air System Sensible Heating Energy,hourly; !- HVAC Sum [J] + Output:Variable,*,Zone Air System Sensible Cooling Energy,hourly; !- HVAC Sum [J] + Output:Variable,*,Zone Air System Sensible Heating Rate,hourly; !- HVAC Average [W] + Output:Variable,*,Zone Air System Sensible Cooling Rate,hourly; !- HVAC Average [W] + Output:Variable,*,Zone Predicted Sensible Load to Setpoint Heat Transfer Rate,hourly; !- HVAC Average [W] + Output:Variable,*,Zone Predicted Sensible Load to Heating Setpoint Heat Transfer Rate,hourly; !- HVAC Average [W] + Output:Variable,*,Zone Predicted Sensible Load to Cooling Setpoint Heat Transfer Rate,hourly; !- HVAC Average [W] + Output:Variable,*,Zone System Predicted Sensible Load to Setpoint Heat Transfer Rate,hourly; !- HVAC Average [W] + Output:Variable,*,Zone System Predicted Sensible Load to Heating Setpoint Heat Transfer Rate,hourly; !- HVAC Average [W] + Output:Variable,*,Zone System Predicted Sensible Load to Cooling Setpoint Heat Transfer Rate,hourly; !- HVAC Average [W] + + Output:Variable,*,Space Air System Sensible Heating Energy,hourly; !- HVAC Sum [J] + Output:Variable,*,Space Air System Sensible Cooling Energy,hourly; !- HVAC Sum [J] + Output:Variable,*,Space Air System Sensible Heating Rate,hourly; !- HVAC Average [W] + Output:Variable,*,Space Air System Sensible Cooling Rate,hourly; !- HVAC Average [W] + Output:Variable,*,Space Predicted Sensible Load to Setpoint Heat Transfer Rate,hourly; !- HVAC Average [W] + Output:Variable,*,Space Predicted Sensible Load to Heating Setpoint Heat Transfer Rate,hourly; !- HVAC Average [W] + Output:Variable,*,Space Predicted Sensible Load to Cooling Setpoint Heat Transfer Rate,hourly; !- HVAC Average [W] + Output:Variable,*,Space System Predicted Sensible Load to Setpoint Heat Transfer Rate,hourly; !- HVAC Average [W] + Output:Variable,*,Space System Predicted Sensible Load to Heating Setpoint Heat Transfer Rate,hourly; !- HVAC Average [W] + Output:Variable,*,Space System Predicted Sensible Load to Cooling Setpoint Heat Transfer Rate,hourly; !- HVAC Average [W] + + Output:Variable,*,Zone Predicted Moisture Load Moisture Transfer Rate,hourly; !- HVAC Average [kgWater/s] + Output:Variable,*,Zone Predicted Moisture Load to Humidifying Setpoint Moisture Transfer Rate,hourly; !- HVAC Average [kgWater/s] + Output:Variable,*,Zone Predicted Moisture Load to Dehumidifying Setpoint Moisture Transfer Rate,hourly; !- HVAC Average [kgWater/s] + Output:Variable,*,Zone System Predicted Moisture Load Moisture Transfer Rate,hourly; !- HVAC Average [kgWater/s] + Output:Variable,*,Zone System Predicted Moisture Load to Humidifying Setpoint Moisture Transfer Rate,hourly; !- HVAC Average [kgWater/s] + Output:Variable,*,Zone System Predicted Moisture Load to Dehumidifying Setpoint Moisture Transfer Rate,hourly; !- HVAC Average [kgWater/s] + + Output:Variable,*,Space Predicted Moisture Load Moisture Transfer Rate,hourly; !- HVAC Average [kgWater/s] + Output:Variable,*,Space Predicted Moisture Load to Humidifying Setpoint Moisture Transfer Rate,hourly; !- HVAC Average [kgWater/s] + Output:Variable,*,Space Predicted Moisture Load to Dehumidifying Setpoint Moisture Transfer Rate,hourly; !- HVAC Average [kgWater/s] + Output:Variable,*,Space System Predicted Moisture Load Moisture Transfer Rate,hourly; !- HVAC Average [kgWater/s] + Output:Variable,*,Space System Predicted Moisture Load to Humidifying Setpoint Moisture Transfer Rate,hourly; !- HVAC Average [kgWater/s] + Output:Variable,*,Space System Predicted Moisture Load to Dehumidifying Setpoint Moisture Transfer Rate,hourly; !- HVAC Average [kgWater/s] + + Output:Variable,*,Zone Air Humidity Ratio,hourly; !- HVAC Average [] + Output:Variable,*,Zone Air Relative Humidity,hourly; !- HVAC Average [%] + + Output:Variable,*,Space Air Humidity Ratio,hourly; !- HVAC Average [] + Output:Variable,*,Space Air Relative Humidity,hourly; !- HVAC Average [%] + + Output:VariableDictionary,IDF; + + Output:Meter:MeterFileOnly,Electricity:Facility,monthly; + + Output:Meter:MeterFileOnly,Electricity:Building,monthly; + + Output:Meter:MeterFileOnly,InteriorLights:Electricity,monthly; + + Output:Meter:MeterFileOnly,Electricity:HVAC,monthly; + + Output:Meter:MeterFileOnly,Electricity:Plant,monthly; + + Output:Meter:MeterFileOnly,NaturalGas:Facility,monthly; + + Output:Meter:MeterFileOnly,NaturalGas:Plant,monthly; + + Output:Meter:MeterFileOnly,Electricity:Facility,runperiod; + + Output:Meter:MeterFileOnly,Electricity:Building,runperiod; + + Output:Meter:MeterFileOnly,InteriorLights:Electricity,runperiod; + + Output:Meter:MeterFileOnly,Electricity:HVAC,runperiod; + + Output:Meter:MeterFileOnly,Electricity:Plant,runperiod; + + Output:Meter:MeterFileOnly,NaturalGas:Facility,runperiod; + + Output:Meter:MeterFileOnly,NaturalGas:Plant,runperiod; + + Output:Meter:MeterFileOnly,MyGeneralLights,monthly; + + Output:Meter:MeterFileOnly,MyGeneralLights,runperiod; + + Output:Meter:MeterFileOnly,MyBuildingElectric,monthly; + + Output:Meter:MeterFileOnly,MyBuildingElectric,runperiod; + + Output:Meter:MeterFileOnly,MyBuildingOther,monthly; + + Output:Meter:MeterFileOnly,MyBuildingOther,runperiod; + +! The following custom meters are set up to illustrate the capabilities +! of custom meters. +! Custom Meter "MyGeneralLights" duplicates the InteriorLights:Electricity meter. +! Custom Meter "MyBuildingElectric" duplicates the Electricity:Building meter (by specifying that meter). +! Custom Meter (Decrement) "MyBuildingOther" uses Electricity:Building as its source meter +! and subtracts out the values for MyGeneralLights (aka InteriorLights:Electricity). The +! resultant value for MyBuildingOther should be equal to the value for the meters +! Electricity:Building - InteriorLights:Electricity (aka MyGeneralLights) + + Meter:Custom, + MyGeneralLights, !- Name + Electricity, !- Resource Type + SPACE1-1 Lights 1, !- Key Name 1 + Lights Electricity Energy, !- Output Variable or Meter Name 1 + SPACE2-1 Lights 1, !- Key Name 2 + Lights Electricity Energy, !- Output Variable or Meter Name 2 + SPACE3-1 Lights 1, !- Key Name 3 + Lights Electricity Energy, !- Output Variable or Meter Name 3 + SPACE4-1 Lights 1, !- Key Name 4 + Lights Electricity Energy, !- Output Variable or Meter Name 4 + SPACE5-1 Lights 1, !- Key Name 5 + Lights Electricity Energy; !- Output Variable or Meter Name 5 + + Meter:Custom, + MyBuildingElectric, !- Name + Electricity, !- Resource Type + , !- Key Name 1 + Electricity:Building; !- Output Variable or Meter Name 1 + + Meter:CustomDecrement, + MyBuildingOther, !- Name + Electricity, !- Resource Type + Electricity:Building, !- Source Meter Name + , !- Key Name 1 + MyGeneralLights; !- Output Variable or Meter Name 1 + + Output:Surfaces:Drawing,VRML; + + OutputControl:Table:Style, + HTML; !- Column Separator + + Output:Table:SummaryReports, + AllSummary, !- Report 1 Name + ZoneComponentLoadSummary;!- Report 2 Name + + Output:Surfaces:List,Details; + + Output:Surfaces:List,DecayCurvesFromComponentLoadsSummary; + + Output:Surfaces:List,ViewFactorInfo; + diff --git a/testfiles/CMakeLists.txt b/testfiles/CMakeLists.txt index 1b30a103881..abb7bffd4d5 100644 --- a/testfiles/CMakeLists.txt +++ b/testfiles/CMakeLists.txt @@ -48,6 +48,7 @@ add_simulation_test(IDF_FILE 4ZoneWithShading_Simple_2.idf EPW_FILE USA_CO_Golde add_simulation_test(IDF_FILE 5ZoneAirCooled.idf EPW_FILE USA_CO_Golden-NREL.724666_TMY3.epw) add_simulation_test(IDF_FILE 5ZoneAirCooledConvCoef.idf EPW_FILE USA_CO_Golden-NREL.724666_TMY3.epw) add_simulation_test(IDF_FILE 5ZoneAirCooledWithSpaces.idf PW_FILE USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.epw) +add_simulation_test(IDF_FILE 5ZoneAirCooledWithSpaceHeatBalance.idf PW_FILE USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.epw) add_simulation_test(IDF_FILE 5ZoneAirCooledDemandLimiting.idf EPW_FILE USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.epw) add_simulation_test(IDF_FILE 5ZoneAirCooledDemandLimiting_FixedRateVentilation.idf EPW_FILE USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.epw) add_simulation_test(IDF_FILE 5ZoneAirCooledDemandLimiting_ReductionRatioVentilation.idf EPW_FILE USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.epw) diff --git a/tst/EnergyPlus/unit/AdvancedAFN.unit.cc b/tst/EnergyPlus/unit/AdvancedAFN.unit.cc index af03bc37a52..db723030bdc 100644 --- a/tst/EnergyPlus/unit/AdvancedAFN.unit.cc +++ b/tst/EnergyPlus/unit/AdvancedAFN.unit.cc @@ -57,6 +57,7 @@ #include #include #include +#include #include "Fixtures/EnergyPlusFixture.hh" @@ -102,9 +103,9 @@ TEST_F(EnergyPlusFixture, AirflowNetwork_AdvancedTest_Test1) state->dataEnvrn->OutDryBulbTemp = 15.0; state->dataHeatBal->Zone.allocate(1); - state->dataHeatBalFanSys->MAT.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); state->dataHeatBal->ZoneMRT.allocate(1); - state->dataHeatBalFanSys->MAT(1) = 22.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 22.0; state->dataHeatBal->ZoneMRT(1) = 22.0; TimeOpenElapsed = 5.0; @@ -149,7 +150,7 @@ TEST_F(EnergyPlusFixture, AirflowNetwork_AdvancedTest_Test1) EXPECT_EQ(0, OpenProbStatus); EXPECT_EQ(1, CloseProbStatus); - state->dataHeatBalFanSys->MAT(1) = 26.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 26.0; state->dataHeatBal->ZoneMRT(1) = 26.0; state->afn->OccupantVentilationControl(1).calc(*state, 1, TimeOpenElapsed, TimeCloseElapsed, OpenStatus, OpenProbStatus, CloseProbStatus); EXPECT_EQ(2, OpenProbStatus); diff --git a/tst/EnergyPlus/unit/AirflowNetworkConditions.unit.cc b/tst/EnergyPlus/unit/AirflowNetworkConditions.unit.cc index 6826abcf9f5..91899f3a09c 100644 --- a/tst/EnergyPlus/unit/AirflowNetworkConditions.unit.cc +++ b/tst/EnergyPlus/unit/AirflowNetworkConditions.unit.cc @@ -57,7 +57,6 @@ #include #include #include -#include #include #include #include @@ -67,6 +66,7 @@ #include #include #include +#include #include "Fixtures/EnergyPlusFixture.hh" @@ -6018,10 +6018,9 @@ TEST_F(EnergyPlusFixture, AirflowNetwork_BasicAdvancedSingleSidedAvoidCrashTest) EXPECT_EQ(0, state->dataCurveManager->NumCurves); // #6912 - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); - state->dataHeatBalFanSys->MAT(1) = 23.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 23.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.001; state->dataEnvrn->OutDryBulbTemp = -17.29025; state->dataEnvrn->OutHumRat = 0.0008389; state->dataEnvrn->OutBaroPress = 99063.0; diff --git a/tst/EnergyPlus/unit/AirflowNetworkHVAC.unit.cc b/tst/EnergyPlus/unit/AirflowNetworkHVAC.unit.cc index a51e6905945..c62c18af584 100644 --- a/tst/EnergyPlus/unit/AirflowNetworkHVAC.unit.cc +++ b/tst/EnergyPlus/unit/AirflowNetworkHVAC.unit.cc @@ -82,6 +82,7 @@ #include #include #include +#include #include "Fixtures/EnergyPlusFixture.hh" @@ -2236,19 +2237,19 @@ TEST_F(EnergyPlusFixture, AirflowNetwork_TestPressureStat) EXPECT_EQ(0.0, state->dataSurface->SurfWinVentingOpenFactorMultRep(14)); // Test for #7162 - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(4); - state->dataHeatBalFanSys->MAT.allocate(4); - state->dataHeatBalFanSys->ZoneAirHumRatAvg.allocate(state->dataGlobal->NumOfZones); - - state->dataHeatBalFanSys->MAT(1) = 23.0; - state->dataHeatBalFanSys->MAT(2) = 23.0; - state->dataHeatBalFanSys->MAT(3) = 23.0; - state->dataHeatBalFanSys->MAT(4) = 5.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.0007; - state->dataHeatBalFanSys->ZoneAirHumRat(2) = 0.0011; - state->dataHeatBalFanSys->ZoneAirHumRat(3) = 0.0012; - state->dataHeatBalFanSys->ZoneAirHumRat(4) = 0.0008; - state->dataHeatBalFanSys->ZoneAirHumRatAvg = state->dataHeatBalFanSys->ZoneAirHumRat; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(state->dataGlobal->NumOfZones); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 23.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MAT = 23.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(3).MAT = 23.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(4).MAT = 5.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.0007; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).ZoneAirHumRat = 0.0011; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(3).ZoneAirHumRat = 0.0012; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(4).ZoneAirHumRat = 0.0008; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvg = 0.0007; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).ZoneAirHumRatAvg = 0.0011; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(3).ZoneAirHumRatAvg = 0.0012; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(4).ZoneAirHumRatAvg = 0.0008; state->dataZoneEquip->ZoneEquipConfig.allocate(4); state->dataZoneEquip->ZoneEquipConfig(1).IsControlled = false; state->dataZoneEquip->ZoneEquipConfig(2).IsControlled = false; @@ -2271,14 +2272,15 @@ TEST_F(EnergyPlusFixture, AirflowNetwork_TestPressureStat) EXPECT_NEAR(38.1554377, state->afn->AirflowNetworkReportData(2).MultiZoneMixLatGainW, 0.0001); EXPECT_NEAR(91.8528571, state->afn->AirflowNetworkReportData(3).MultiZoneInfiLatLossW, 0.0001); - Real64 hg = Psychrometrics::PsyHgAirFnWTdb(state->dataHeatBalFanSys->ZoneAirHumRat(1), state->dataHeatBalFanSys->MAT(1)); - Real64 hzone = Psychrometrics::PsyHFnTdbW(state->dataHeatBalFanSys->MAT(1), state->dataHeatBalFanSys->ZoneAirHumRat(1)); + auto &thisZoneHB = state->dataZoneTempPredictorCorrector->zoneHeatBalance(1); + Real64 hg = Psychrometrics::PsyHgAirFnWTdb(thisZoneHB.ZoneAirHumRat, thisZoneHB.MAT); + Real64 hzone = Psychrometrics::PsyHFnTdbW(thisZoneHB.MAT, thisZoneHB.ZoneAirHumRat); Real64 hamb = Psychrometrics::PsyHFnTdbW(0.0, state->dataEnvrn->OutHumRat); Real64 hdiff = state->afn->AirflowNetworkLinkSimu(1).FLOW2 * (hzone - hamb); Real64 sum = state->afn->AirflowNetworkReportData(1).MultiZoneInfiSenLossW - state->afn->AirflowNetworkReportData(1).MultiZoneInfiLatGainW; // Existing code uses T_average to calculate hg, get close results EXPECT_NEAR(hdiff, sum, 0.4); - Real64 dhlatent = state->afn->AirflowNetworkLinkSimu(1).FLOW2 * hg * (state->dataHeatBalFanSys->ZoneAirHumRat(1) - state->dataEnvrn->OutHumRat); + Real64 dhlatent = state->afn->AirflowNetworkLinkSimu(1).FLOW2 * hg * (thisZoneHB.ZoneAirHumRat - state->dataEnvrn->OutHumRat); // when hg is calculated with indoor temperature, get exact results sum = state->afn->AirflowNetworkReportData(1).MultiZoneInfiSenLossW + dhlatent; EXPECT_NEAR(hdiff, sum, 0.001); @@ -6008,13 +6010,13 @@ TEST_F(EnergyPlusFixture, AirflowNetwork_MultiAirLoopTest) state->afn->AirflowNetworkFanActivated = false; // #7977 state->afn->calculate_balance(); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(5); - state->dataHeatBalFanSys->MAT.allocate(5); - state->dataHeatBalFanSys->ZoneAirHumRatAvg.allocate(5); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(5); state->dataZoneEquip->ZoneEquipConfig.allocate(5); - state->dataHeatBalFanSys->MAT = 23.0; - state->dataHeatBalFanSys->ZoneAirHumRat = 0.001; - state->dataHeatBalFanSys->ZoneAirHumRatAvg = state->dataHeatBalFanSys->ZoneAirHumRat; + for (auto &thisZoneHB : state->dataZoneTempPredictorCorrector->zoneHeatBalance) { + thisZoneHB.MAT = 23.0; + thisZoneHB.ZoneAirHumRat = 0.001; + thisZoneHB.ZoneAirHumRatAvg = 0.001; + } state->dataHeatBal->Zone(1).OutDryBulbTemp = state->dataEnvrn->OutDryBulbTemp; state->dataHeatBal->Zone(2).OutDryBulbTemp = state->dataEnvrn->OutDryBulbTemp; state->dataHeatBal->Zone(3).OutDryBulbTemp = state->dataEnvrn->OutDryBulbTemp; @@ -10468,18 +10470,17 @@ TEST_F(EnergyPlusFixture, DISABLED_AirLoopNumTest) state->afn->AirflowNetworkFanActivated = false; - state->dataHeatBalFanSys->MAT.allocate(5); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(5); - state->dataHeatBalFanSys->MAT(1) = 23.0; - state->dataHeatBalFanSys->MAT(2) = 23.0; - state->dataHeatBalFanSys->MAT(3) = 23.0; - state->dataHeatBalFanSys->MAT(4) = 23.0; - state->dataHeatBalFanSys->MAT(5) = 23.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.001; - state->dataHeatBalFanSys->ZoneAirHumRat(2) = 0.001; - state->dataHeatBalFanSys->ZoneAirHumRat(3) = 0.001; - state->dataHeatBalFanSys->ZoneAirHumRat(4) = 0.001; - state->dataHeatBalFanSys->ZoneAirHumRat(5) = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(5); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 23.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MAT = 23.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(3).MAT = 23.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(4).MAT = 23.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(5).MAT = 23.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).ZoneAirHumRat = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(3).ZoneAirHumRat = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(4).ZoneAirHumRat = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(5).ZoneAirHumRat = 0.001; DataZoneEquipment::GetZoneEquipmentData(*state); ZoneAirLoopEquipmentManager::GetZoneAirLoopEquipment(*state); @@ -16227,14 +16228,11 @@ TEST_F(EnergyPlusFixture, AirflowNetwork_DuctSizingTest) state->afn->simulation_control.ductSizing.return_trunk_pressure_loss = 3.0; state->afn->simulation_control.ductSizing.return_branch_pressure_loss = 4.0; - state->dataHeatBalFanSys->MAT.allocate(3); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(3); - state->dataHeatBalFanSys->MAT(1) = 23.0; - state->dataHeatBalFanSys->MAT(2) = 23.0; - state->dataHeatBalFanSys->MAT(3) = 23.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.0008400; - state->dataHeatBalFanSys->ZoneAirHumRat(2) = 0.0008400; - state->dataHeatBalFanSys->ZoneAirHumRat(3) = 0.0008400; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(3); + for (auto &thisZoneHB : state->dataZoneTempPredictorCorrector->zoneHeatBalance) { + thisZoneHB.MAT = 23.0; + thisZoneHB.ZoneAirHumRat = 0.0008400; + } state->dataZoneEquip->ZoneEquipList(1).EquipIndex(1) = 1; state->dataDefineEquipment->AirDistUnit(1).MassFlowRateTU = 1.23; diff --git a/tst/EnergyPlus/unit/ChilledCeilingPanelSimple.unit.cc b/tst/EnergyPlus/unit/ChilledCeilingPanelSimple.unit.cc index 74d1ee22379..36cbd909e97 100644 --- a/tst/EnergyPlus/unit/ChilledCeilingPanelSimple.unit.cc +++ b/tst/EnergyPlus/unit/ChilledCeilingPanelSimple.unit.cc @@ -56,6 +56,7 @@ #include #include #include +#include #include "Fixtures/EnergyPlusFixture.hh" @@ -75,8 +76,8 @@ TEST_F(EnergyPlusFixture, SetCoolingPanelControlTemp) ZoneNum = 1; state->dataChilledCeilingPanelSimple->CoolingPanel.allocate(1); - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->MAT(1) = 22.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 22.0; state->dataHeatBal->ZoneMRT.allocate(1); state->dataHeatBal->ZoneMRT(1) = 20.0; state->dataHeatBal->Zone.allocate(1); diff --git a/tst/EnergyPlus/unit/ConvectionCoefficients.unit.cc b/tst/EnergyPlus/unit/ConvectionCoefficients.unit.cc index c17dfe0ec15..0754414240f 100644 --- a/tst/EnergyPlus/unit/ConvectionCoefficients.unit.cc +++ b/tst/EnergyPlus/unit/ConvectionCoefficients.unit.cc @@ -60,7 +60,6 @@ #include #include #include -#include #include #include #include @@ -71,6 +70,7 @@ #include #include #include +#include #include "Fixtures/EnergyPlusFixture.hh" @@ -824,8 +824,9 @@ TEST_F(ConvectionCoefficientsFixture, initIntConvCoeffAdjRatio) state->dataHeatBalSurf->SurfWinCoeffAdjRatio.dimension(7, 1.0); state->dataHeatBalSurf->SurfTempInTmp.dimension(7, 20.0); - state->dataHeatBalFanSys->MAT.dimension(1, 25.0); - state->dataHeatBalFanSys->ZoneAirHumRatAvg.dimension(1, 0.006); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 25.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvg = 0.006; state->dataHeatBalSurf->SurfHConvInt.allocate(7); state->dataHeatBalSurf->SurfHConvInt(7) = 0.0; @@ -934,7 +935,7 @@ TEST_F(ConvectionCoefficientsFixture, DynamicIntConvSurfaceClassification) } // Case 1 - Zone air warmer than surfaces - state->dataHeatBalFanSys->MAT(1) = 30.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 30.0; DynamicIntConvSurfaceClassification(*state, 1); EXPECT_TRUE(compare_enums(state->dataSurface->SurfIntConvClassification(1), ConvectionConstants::InConvClass::A3_VertWalls)); @@ -983,7 +984,7 @@ TEST_F(ConvectionCoefficientsFixture, DynamicIntConvSurfaceClassification) EXPECT_TRUE(compare_enums(state->dataSurface->SurfIntConvClassification(15), ConvectionConstants::InConvClass::A3_UnstableHoriz)); // Case 2 - Zone air colder than surfaces - state->dataHeatBalFanSys->MAT(1) = 10.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 10.0; DynamicIntConvSurfaceClassification(*state, 1); EXPECT_TRUE(compare_enums(state->dataSurface->SurfIntConvClassification(1), ConvectionConstants::InConvClass::A3_VertWalls)); @@ -1067,8 +1068,8 @@ TEST_F(ConvectionCoefficientsFixture, EvaluateIntHcModelsFisherPedersen) state->dataHeatBalSurf->SurfInsideTempHist(1)(surf) = 20.0; } - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->MAT(1) = 30.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 30.0; // Case 1 - Low ACH (should default to CalcASHRAETARPNatural) Real64 ACH = 0.25; @@ -1080,8 +1081,9 @@ TEST_F(ConvectionCoefficientsFixture, EvaluateIntHcModelsFisherPedersen) Hc = 0.0; state->dataSurface->Surface(SurfNum).CosTilt = -1; - HcExpectedValue = CalcASHRAETARPNatural( - state->dataHeatBalSurf->SurfInsideTempHist(1)(1), state->dataHeatBalFanSys->MAT(1), -state->dataSurface->Surface(SurfNum).CosTilt); + HcExpectedValue = CalcASHRAETARPNatural(state->dataHeatBalSurf->SurfInsideTempHist(1)(1), + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT, + -state->dataSurface->Surface(SurfNum).CosTilt); EvaluateIntHcModels(*state, SurfNum, ConvModelEquationNum, Hc); EXPECT_EQ(state->dataSurface->SurfTAirRef(SurfNum), DataSurfaces::RefAirTemp::ZoneMeanAirTemp); @@ -1092,8 +1094,9 @@ TEST_F(ConvectionCoefficientsFixture, EvaluateIntHcModelsFisherPedersen) Hc = 0.0; state->dataSurface->Surface(SurfNum).CosTilt = 1; - HcExpectedValue = CalcASHRAETARPNatural( - state->dataHeatBalSurf->SurfInsideTempHist(1)(1), state->dataHeatBalFanSys->MAT(1), -state->dataSurface->Surface(SurfNum).CosTilt); + HcExpectedValue = CalcASHRAETARPNatural(state->dataHeatBalSurf->SurfInsideTempHist(1)(1), + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT, + -state->dataSurface->Surface(SurfNum).CosTilt); EvaluateIntHcModels(*state, SurfNum, ConvModelEquationNum, Hc); EXPECT_EQ(state->dataSurface->SurfTAirRef(SurfNum), DataSurfaces::RefAirTemp::ZoneMeanAirTemp); @@ -1104,8 +1107,9 @@ TEST_F(ConvectionCoefficientsFixture, EvaluateIntHcModelsFisherPedersen) Hc = 0.0; state->dataSurface->Surface(SurfNum).CosTilt = 0; - HcExpectedValue = CalcASHRAETARPNatural( - state->dataHeatBalSurf->SurfInsideTempHist(1)(1), state->dataHeatBalFanSys->MAT(1), -state->dataSurface->Surface(SurfNum).CosTilt); + HcExpectedValue = CalcASHRAETARPNatural(state->dataHeatBalSurf->SurfInsideTempHist(1)(1), + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT, + -state->dataSurface->Surface(SurfNum).CosTilt); EvaluateIntHcModels(*state, SurfNum, ConvModelEquationNum, Hc); EXPECT_EQ(state->dataSurface->SurfTAirRef(SurfNum), DataSurfaces::RefAirTemp::ZoneMeanAirTemp); diff --git a/tst/EnergyPlus/unit/CoolTower.unit.cc b/tst/EnergyPlus/unit/CoolTower.unit.cc index d7242e6f86a..7b63d4da732 100644 --- a/tst/EnergyPlus/unit/CoolTower.unit.cc +++ b/tst/EnergyPlus/unit/CoolTower.unit.cc @@ -57,6 +57,7 @@ #include #include #include +#include using namespace EnergyPlus; @@ -84,18 +85,13 @@ TEST_F(EnergyPlusFixture, ExerciseCoolTower) ASSERT_TRUE(process_idf(idf_objects, false)); state->dataHeatBal->Zone.allocate(1); state->dataHeatBal->Zone(1).Name = "ZONE 1"; - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->MAT(1) = 20.0; - state->dataHeatBalFanSys->MCPC.allocate(1); - state->dataHeatBalFanSys->MCPC(1) = 1; - state->dataHeatBalFanSys->MCPTC.allocate(1); - state->dataHeatBalFanSys->MCPTC(1) = 1; - state->dataHeatBalFanSys->CTMFL.allocate(1); - state->dataHeatBalFanSys->CTMFL(1) = 1; - state->dataHeatBalFanSys->ZT.allocate(1); - state->dataHeatBalFanSys->ZT(1) = 1; - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 1; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 20.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZT = 1.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MCPC = 1; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MCPTC = 1; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).CTMFL = 1; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 1; state->dataEnvrn->WindSpeed = 20.0; CoolTower::ManageCoolTower(*state); // auto &thisTower = state->dataCoolTower->CoolTowerSys(1); diff --git a/tst/EnergyPlus/unit/CrossVentMgr.unit.cc b/tst/EnergyPlus/unit/CrossVentMgr.unit.cc index 3e02b2e83b2..2e208652db7 100644 --- a/tst/EnergyPlus/unit/CrossVentMgr.unit.cc +++ b/tst/EnergyPlus/unit/CrossVentMgr.unit.cc @@ -64,6 +64,7 @@ #include #include #include +#include using namespace EnergyPlus; using namespace CrossVentMgr; @@ -77,6 +78,7 @@ TEST_F(EnergyPlusFixture, CrossVentMgr_EvolveParaUCSDCV_Test) int MaxSurf = 2; state->dataRoomAirMod->RecInflowRatio.allocate(state->dataGlobal->NumOfZones); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(state->dataGlobal->NumOfZones); state->dataRoomAirMod->AirflowNetworkSurfaceUCSDCV.allocate({0, MaxSurf}, state->dataGlobal->NumOfZones); state->dataRoomAirMod->AirflowNetworkSurfaceUCSDCV(1, 1) = 1; diff --git a/tst/EnergyPlus/unit/DOASEffectOnZoneSizing.unit.cc b/tst/EnergyPlus/unit/DOASEffectOnZoneSizing.unit.cc index 87e09296220..b449ad7a846 100644 --- a/tst/EnergyPlus/unit/DOASEffectOnZoneSizing.unit.cc +++ b/tst/EnergyPlus/unit/DOASEffectOnZoneSizing.unit.cc @@ -66,6 +66,7 @@ #include #include #include +#include using namespace EnergyPlus; using namespace ZoneEquipmentManager; @@ -145,8 +146,7 @@ TEST_F(EnergyPlusFixture, DOASEffectOnZoneSizing_SizeZoneEquipment) state->dataHeatBal->Zone.allocate(2); state->dataSize->CalcZoneSizing.allocate(1, 2); state->dataSize->CalcFinalZoneSizing.allocate(2); - state->dataHeatBalFanSys->NonAirSystemResponse.allocate(2); - state->dataHeatBalFanSys->SysDepZoneLoads.allocate(2); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(2); state->dataZoneEquip->ZoneEquipConfig.allocate(2); state->dataHeatBalFanSys->TempControlType.allocate(2); state->dataHeatBalFanSys->TempZoneThermostatSetPoint.allocate(2); @@ -310,28 +310,6 @@ TEST_F(EnergyPlusFixture, DOASEffectOnZoneSizing_SizeZoneEquipment) EXPECT_DOUBLE_EQ(0.0, state->dataSize->CalcZoneSizing(1, 2).HeatMassFlow); EXPECT_NEAR(1444.767, state->dataSize->CalcZoneSizing(1, 2).CoolLoad, .001); EXPECT_NEAR(.127528, state->dataSize->CalcZoneSizing(1, 2).CoolMassFlow, .000001); - - state->dataLoopNodes->Node.deallocate(); - state->dataSize->ZoneEqSizing.deallocate(); - state->dataHeatBal->Zone.deallocate(); - state->dataSize->CalcZoneSizing.deallocate(); - state->dataHeatBalFanSys->NonAirSystemResponse.deallocate(); - state->dataHeatBalFanSys->SysDepZoneLoads.deallocate(); - state->dataZoneEquip->ZoneEquipConfig(1).InletNode.deallocate(); - state->dataZoneEquip->ZoneEquipConfig(2).InletNode.deallocate(); - state->dataZoneEquip->ZoneEquipConfig(1).ExhaustNode.deallocate(); - state->dataZoneEquip->ZoneEquipConfig(2).ExhaustNode.deallocate(); - state->dataZoneEquip->ZoneEquipConfig.deallocate(); - state->dataHeatBalFanSys->TempControlType.deallocate(); - state->dataHeatBalFanSys->TempZoneThermostatSetPoint.deallocate(); - state->dataHeatBalFanSys->ZoneThermostatSetPointLo.deallocate(); - state->dataHeatBalFanSys->ZoneThermostatSetPointHi.deallocate(); - state->dataZoneEnergyDemand->ZoneSysEnergyDemand.deallocate(); - state->dataZoneEnergyDemand->ZoneSysMoistureDemand.deallocate(); - state->dataZoneEnergyDemand->DeadBandOrSetback.deallocate(); - state->dataZoneEnergyDemand->CurDeadBandOrSetback.deallocate(); - state->dataHeatBalFanSys->ZoneMassBalanceFlag.deallocate(); - state->dataHeatBal->MassConservation.deallocate(); } TEST_F(EnergyPlusFixture, TestAutoCalcDOASControlStrategy) diff --git a/tst/EnergyPlus/unit/DaylightingManager.unit.cc b/tst/EnergyPlus/unit/DaylightingManager.unit.cc index 216e671828f..cb9666d1e30 100644 --- a/tst/EnergyPlus/unit/DaylightingManager.unit.cc +++ b/tst/EnergyPlus/unit/DaylightingManager.unit.cc @@ -1424,7 +1424,7 @@ TEST_F(EnergyPlusFixture, DaylightingManager_DayltgInteriorIllum_LuminanceShadin DaylightingManager::GetInputDayliteRefPt(*state, foundErrors); DaylightingManager::GetDaylightingParametersInput(*state); - int ISurf = state->dataHeatBal->Zone(ZoneNum).WindowSurfaceFirst; + int ISurf = state->dataHeatBal->space(state->dataHeatBal->Zone(ZoneNum).spaceIndexes[0]).WindowSurfaceFirst; // Set the following values to make thisDaylightControl.SourceLumFromWinAtRefPt much larger than // luminance threshold of 2000 (WindowShadingControl SetPoint2) diff --git a/tst/EnergyPlus/unit/EMSManager.unit.cc b/tst/EnergyPlus/unit/EMSManager.unit.cc index 7f915a06336..39346bef648 100644 --- a/tst/EnergyPlus/unit/EMSManager.unit.cc +++ b/tst/EnergyPlus/unit/EMSManager.unit.cc @@ -75,6 +75,7 @@ #include #include #include +#include using namespace EnergyPlus; using namespace EnergyPlus::EMSManager; @@ -1636,10 +1637,13 @@ TEST_F(EnergyPlusFixture, EMSManager_TestWindowShadingControlExteriorScreenOptio EXPECT_FALSE(state->dataSurface->SurfWinShadingFlagEMSOn(2)); EXPECT_EQ(state->dataSurface->SurfWinShadingFlagEMSValue(2), 0.0); + state->dataHeatBal->space.allocate(1); + state->dataHeatBal->space(1).WindowSurfaceFirst = 1; + state->dataHeatBal->space(1).WindowSurfaceLast = 2; state->dataHeatBal->Zone.allocate(1); - state->dataHeatBal->Zone(1).WindowSurfaceFirst = 1; - state->dataHeatBal->Zone(1).WindowSurfaceLast = 2; + state->dataHeatBal->Zone(1).spaceIndexes.emplace_back(1); state->dataGlobal->NumOfZones = 1; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); state->dataSurface->SurfWinShadingFlagEMSOn(2) = true; state->dataSurface->SurfWinShadingFlagEMSValue(2) = 1.0; // WinShadingType::IntShade SolarShading::WindowShadingManager(*state); diff --git a/tst/EnergyPlus/unit/EarthTube.unit.cc b/tst/EnergyPlus/unit/EarthTube.unit.cc index 0583cb96f8d..9f41f3bc8fa 100644 --- a/tst/EnergyPlus/unit/EarthTube.unit.cc +++ b/tst/EnergyPlus/unit/EarthTube.unit.cc @@ -56,6 +56,7 @@ #include #include #include +#include using namespace EnergyPlus; using namespace EnergyPlus::EarthTube; @@ -86,12 +87,9 @@ TEST_F(EnergyPlusFixture, EarthTube_CalcEarthTubeHumRatTest) state->dataEarthTube->EarthTubeSys(ETnum).FanPower = 0.05; // Allocate and set any zone variables necessary to run the tests - state->dataHeatBalFanSys->MCPE.allocate(ZNnum); - state->dataHeatBalFanSys->MCPTE.allocate(ZNnum); - state->dataHeatBalFanSys->EAMFL.allocate(ZNnum); - state->dataHeatBalFanSys->EAMFLxHumRat.allocate(ZNnum); - state->dataHeatBalFanSys->MCPE(ZNnum) = 0.05; - state->dataHeatBalFanSys->EAMFL(ZNnum) = 0.05; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(ZNnum); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(ZNnum).MCPE = 0.05; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(ZNnum).EAMFL = 0.05; // First case--no condensation so inside humidity ratio should be the same as the outdoor humidity ratio state->dataEarthTube->EarthTubeSys(ETnum).CalcEarthTubeHumRat(*state, ZNnum); diff --git a/tst/EnergyPlus/unit/HVACManager.unit.cc b/tst/EnergyPlus/unit/HVACManager.unit.cc index c0e91b67cc5..6e218940caf 100644 --- a/tst/EnergyPlus/unit/HVACManager.unit.cc +++ b/tst/EnergyPlus/unit/HVACManager.unit.cc @@ -58,7 +58,6 @@ #include #include #include -#include #include #include #include @@ -70,6 +69,7 @@ #include #include #include +#include #include "Fixtures/EnergyPlusFixture.hh" @@ -87,32 +87,31 @@ TEST_F(EnergyPlusFixture, CrossMixingReportTest) int NumOfCrossMixing = 1; state->dataHeatBal->Zone.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->MAT.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(state->dataGlobal->NumOfZones); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(state->dataGlobal->NumOfZones); state->dataHeatBal->CrossMixing.allocate(NumOfCrossMixing); state->dataHeatBal->ZnAirRpt.allocate(state->dataGlobal->NumOfZones); - state->dataZoneEquip->CrossMixingReportFlag.allocate(NumOfCrossMixing); - state->dataHeatBalFanSys->MCPI.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->MCPV.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->ZoneAirHumRatAvg.allocate(state->dataGlobal->NumOfZones); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(state->dataGlobal->NumOfZones); state->dataGlobal->NumOfZones = state->dataGlobal->NumOfZones; state->dataHeatBal->TotCrossMixing = NumOfCrossMixing; - state->dataZoneEquip->CrossMixingReportFlag(1) = true; state->dataHVACGlobal->TimeStepSys = 1.0; - state->dataHeatBalFanSys->MCPI = 0.0; - state->dataHeatBalFanSys->MCPV = 0.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MCPI = 0.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MCPI = 0.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MCPV = 0.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MCPV = 0.0; state->dataEnvrn->OutBaroPress = 101325.0; - state->dataHeatBalFanSys->MAT(1) = 22.0; - state->dataHeatBalFanSys->MAT(2) = 25.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.001; - state->dataHeatBalFanSys->ZoneAirHumRat(2) = 0.0011; - state->dataHeatBalFanSys->ZoneAirHumRatAvg = state->dataHeatBalFanSys->ZoneAirHumRat; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 22.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MAT = 25.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).ZoneAirHumRat = 0.0011; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvg = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).ZoneAirHumRatAvg = 0.0011; state->dataEnvrn->StdRhoAir = 1.20; state->dataHeatBal->CrossMixing(1).ZonePtr = 1; state->dataHeatBal->CrossMixing(1).FromZone = 2; state->dataHeatBal->CrossMixing(1).DesiredAirFlowRate = 0.1; + state->dataHeatBal->CrossMixing(1).ReportFlag = true; state->dataZoneEquip->ZoneEquipConfig.allocate(state->dataGlobal->NumOfZones); state->dataZoneEquip->ZoneEquipConfig(1).NumInletNodes = 0; state->dataZoneEquip->ZoneEquipConfig(2).NumInletNodes = 0; @@ -135,17 +134,6 @@ TEST_F(EnergyPlusFixture, CrossMixingReportTest) EXPECT_NEAR(state->dataHeatBal->ZnAirRpt(1).MixLatentGain, state->dataHeatBal->ZnAirRpt(2).MixLatentLoss, 0.0001); EXPECT_NEAR(state->dataHeatBal->ZnAirRpt(1).MixTotalLoss, state->dataHeatBal->ZnAirRpt(2).MixTotalGain, 0.0001); EXPECT_NEAR(state->dataHeatBal->ZnAirRpt(1).MixTotalGain, state->dataHeatBal->ZnAirRpt(2).MixTotalLoss, 0.0001); - - // Cleanup - state->dataHeatBal->Zone.deallocate(); - state->dataHeatBalFanSys->MAT.deallocate(); - state->dataHeatBalFanSys->ZoneAirHumRat.deallocate(); - state->dataHeatBal->CrossMixing.deallocate(); - state->dataHeatBal->ZnAirRpt.deallocate(); - state->dataZoneEquip->CrossMixingReportFlag.deallocate(); - state->dataHeatBalFanSys->MCPI.deallocate(); - state->dataHeatBalFanSys->MCPV.deallocate(); - state->dataHeatBalFanSys->ZoneAirHumRatAvg.deallocate(); } TEST_F(EnergyPlusFixture, InfiltrationObjectLevelReport) @@ -214,24 +202,18 @@ TEST_F(EnergyPlusFixture, InfiltrationObjectLevelReport) EXPECT_EQ(state->dataHeatBal->TotInfiltration, 4); // one per zone - state->dataHeatBalFanSys->MAT.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->MCPM.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->MCPTM.allocate(state->dataGlobal->NumOfZones); - - state->dataHeatBalFanSys->MCPI.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->OAMFL.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->MCPTI.allocate(state->dataGlobal->NumOfZones); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(state->dataGlobal->NumOfZones); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(state->dataGlobal->NumOfZones); state->dataZoneEquip->ZoneEquipConfig.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->MAT(1) = 21.0; - state->dataHeatBalFanSys->MAT(2) = 22.0; - state->dataHeatBalFanSys->MAT(3) = 23.0; - state->dataHeatBalFanSys->MAT(4) = 24.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.001; - state->dataHeatBalFanSys->ZoneAirHumRat(2) = 0.001; - state->dataHeatBalFanSys->ZoneAirHumRat(3) = 0.001; - state->dataHeatBalFanSys->ZoneAirHumRat(4) = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 21.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MAT = 22.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(3).MAT = 23.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(4).MAT = 24.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).ZoneAirHumRat = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(3).ZoneAirHumRat = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(4).ZoneAirHumRat = 0.001; state->dataHeatBal->AirFlowFlag = true; state->dataEnvrn->OutBaroPress = 101325.0; @@ -258,10 +240,14 @@ TEST_F(EnergyPlusFixture, InfiltrationObjectLevelReport) EXPECT_NEAR(state->dataHeatBal->Infiltration(3).MCpI_temp, 22.486, 0.01); // zone level reporting matches object level EXPECT_NEAR(state->dataHeatBal->Infiltration(4).MCpI_temp, 24.459, 0.01); // zone level reporting matches object level - EXPECT_EQ(state->dataHeatBalFanSys->MCPI(1), state->dataHeatBal->Infiltration(1).MCpI_temp); // zone level reporting matches object level - EXPECT_EQ(state->dataHeatBalFanSys->MCPI(2), state->dataHeatBal->Infiltration(2).MCpI_temp); // zone level reporting matches object level - EXPECT_EQ(state->dataHeatBalFanSys->MCPI(3), state->dataHeatBal->Infiltration(3).MCpI_temp); // zone level reporting matches object level - EXPECT_EQ(state->dataHeatBalFanSys->MCPI(4), state->dataHeatBal->Infiltration(4).MCpI_temp); // zone level reporting matches object level + EXPECT_EQ(state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MCPI, + state->dataHeatBal->Infiltration(1).MCpI_temp); // zone level reporting matches object level + EXPECT_EQ(state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MCPI, + state->dataHeatBal->Infiltration(2).MCpI_temp); // zone level reporting matches object level + EXPECT_EQ(state->dataZoneTempPredictorCorrector->zoneHeatBalance(3).MCPI, + state->dataHeatBal->Infiltration(3).MCpI_temp); // zone level reporting matches object level + EXPECT_EQ(state->dataZoneTempPredictorCorrector->zoneHeatBalance(4).MCPI, + state->dataHeatBal->Infiltration(4).MCpI_temp); // zone level reporting matches object level ReportAirHeatBalance(*state); @@ -384,29 +370,26 @@ TEST_F(EnergyPlusFixture, InfiltrationReportTest) state->dataGlobal->NumOfZones = 2; state->dataHeatBal->Zone.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->MAT.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(state->dataGlobal->NumOfZones); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(state->dataGlobal->NumOfZones); state->dataHeatBal->ZnAirRpt.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->MCPI.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->MCPV.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->ZoneAirHumRatAvg.allocate(state->dataGlobal->NumOfZones); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(state->dataGlobal->NumOfZones); state->dataHeatBal->TotVentilation = 1; state->dataHeatBal->Ventilation.allocate(state->dataHeatBal->TotVentilation); - state->dataZoneEquip->VentMCP.allocate(1); state->dataGlobal->NumOfZones = state->dataGlobal->NumOfZones; state->dataHVACGlobal->TimeStepSys = 1.0; - state->dataHeatBalFanSys->MCPI(1) = 1.0; - state->dataHeatBalFanSys->MCPI(2) = 1.5; - state->dataHeatBalFanSys->MCPV(1) = 2.0; - state->dataHeatBalFanSys->MCPV(2) = 2.5; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MCPI = 1.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MCPI = 1.5; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MCPV = 2.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MCPV = 2.5; state->dataEnvrn->OutBaroPress = 101325.0; state->dataEnvrn->OutHumRat = 0.0005; - state->dataHeatBalFanSys->MAT(1) = 22.0; - state->dataHeatBalFanSys->MAT(2) = 25.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.001; - state->dataHeatBalFanSys->ZoneAirHumRat(2) = 0.0011; - state->dataHeatBalFanSys->ZoneAirHumRatAvg = state->dataHeatBalFanSys->ZoneAirHumRat; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 22.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MAT = 25.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).ZoneAirHumRat = 0.0011; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvg = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).ZoneAirHumRatAvg = 0.0011; state->dataEnvrn->StdRhoAir = 1.20; state->dataHeatBal->Zone(1).OutDryBulbTemp = 20.0; state->dataHeatBal->Zone(2).OutDryBulbTemp = 20.0; @@ -419,7 +402,7 @@ TEST_F(EnergyPlusFixture, InfiltrationReportTest) state->dataZoneEquip->ZoneEquipConfig(2).NumReturnNodes = 0; state->dataHeatBal->Ventilation(1).ZonePtr = 1; state->dataHeatBal->Ventilation(1).AirTemp = state->dataHeatBal->Zone(1).OutDryBulbTemp; - state->dataZoneEquip->VentMCP(1) = state->dataHeatBalFanSys->MCPV(1); + state->dataHeatBal->Ventilation(1).MCP = state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MCPV; // Call HVACManager ReportAirHeatBalance(*state); @@ -433,13 +416,16 @@ TEST_F(EnergyPlusFixture, InfiltrationReportTest) EXPECT_NEAR(7.4569771, state->dataHeatBal->ZnAirRpt(2).VentilVolumeStdDensity, 0.0001); // #8068 - Real64 deltah = state->dataHeatBalFanSys->MCPI(1) / (Psychrometrics::PsyCpAirFnW(state->dataEnvrn->OutHumRat)) * 3600.0 * + Real64 deltah = state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MCPI / (Psychrometrics::PsyCpAirFnW(state->dataEnvrn->OutHumRat)) * + 3600.0 * (Psychrometrics::PsyHFnTdbW(state->dataHeatBal->Zone(1).OutDryBulbTemp, state->dataEnvrn->OutHumRat) - - Psychrometrics::PsyHFnTdbW(state->dataHeatBalFanSys->MAT(1), state->dataHeatBalFanSys->ZoneAirHumRat(1))); + Psychrometrics::PsyHFnTdbW(state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT, + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat)); EXPECT_NEAR(-deltah, state->dataHeatBal->ZnAirRpt(1).InfilTotalLoss, 0.0001); - deltah = state->dataHeatBalFanSys->MCPV(1) / (Psychrometrics::PsyCpAirFnW(state->dataEnvrn->OutHumRat)) * 3600.0 * + deltah = state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MCPV / (Psychrometrics::PsyCpAirFnW(state->dataEnvrn->OutHumRat)) * 3600.0 * (Psychrometrics::PsyHFnTdbW(state->dataHeatBal->Zone(1).OutDryBulbTemp, state->dataEnvrn->OutHumRat) - - Psychrometrics::PsyHFnTdbW(state->dataHeatBalFanSys->MAT(1), state->dataHeatBalFanSys->ZoneAirHumRat(1))); + Psychrometrics::PsyHFnTdbW(state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT, + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat)); EXPECT_NEAR(-deltah, state->dataHeatBal->ZnAirRpt(1).VentilTotalLoss, 0.0001); } @@ -449,26 +435,24 @@ TEST_F(EnergyPlusFixture, ExfilAndExhaustReportTest) state->dataGlobal->NumOfZones = 2; state->dataHeatBal->Zone.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->MAT.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(state->dataGlobal->NumOfZones); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(state->dataGlobal->NumOfZones); state->dataHeatBal->ZnAirRpt.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->MCPI.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->MCPV.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->ZoneAirHumRatAvg.allocate(state->dataGlobal->NumOfZones); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(state->dataGlobal->NumOfZones); state->dataGlobal->NumOfZones = state->dataGlobal->NumOfZones; state->dataHVACGlobal->TimeStepSys = 1.0; - state->dataHeatBalFanSys->MCPI(1) = 1.0; - state->dataHeatBalFanSys->MCPI(2) = 1.5; - state->dataHeatBalFanSys->MCPV(1) = 2.0; - state->dataHeatBalFanSys->MCPV(2) = 2.5; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MCPI = 1.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MCPI = 1.5; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MCPV = 2.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MCPV = 2.5; state->dataEnvrn->OutBaroPress = 101325.0; state->dataEnvrn->OutHumRat = 0.0005; - state->dataHeatBalFanSys->MAT(1) = 22.0; - state->dataHeatBalFanSys->MAT(2) = 25.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.001; - state->dataHeatBalFanSys->ZoneAirHumRat(2) = 0.0011; - state->dataHeatBalFanSys->ZoneAirHumRatAvg = state->dataHeatBalFanSys->ZoneAirHumRat; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 22.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MAT = 25.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).ZoneAirHumRat = 0.0011; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvg = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).ZoneAirHumRatAvg = 0.0011; state->dataEnvrn->StdRhoAir = 1.20; state->dataHeatBal->Zone(1).OutDryBulbTemp = 20.0; state->dataHeatBal->Zone(2).OutDryBulbTemp = 20.0; diff --git a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc index 6196902598f..b1932691e0e 100644 --- a/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc +++ b/tst/EnergyPlus/unit/HVACVariableRefrigerantFlow.unit.cc @@ -91,6 +91,7 @@ #include #include #include +#include using namespace EnergyPlus; using namespace DXCoils; @@ -210,6 +211,7 @@ class AirLoopFixture : public EnergyPlusFixture state->dataAirLoop->AirLoopControlInfo.allocate(1); state->dataZoneEnergyDemand->ZoneSysEnergyDemand.allocate(numZones); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(numZones); state->dataSize->ZoneSizingRunDone = true; state->dataSize->SysSizingRunDone = true; @@ -2925,6 +2927,7 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_CalcVRFIUAirFlow) state->dataDXCoils->DXCoil.allocate(NumCoils); int NumZones = 2; state->dataZoneEnergyDemand->ZoneSysEnergyDemand.allocate(NumZones); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(NumZones); // Common Inputs CoolCoilIndex = 1; @@ -3097,6 +3100,7 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_CalcVRFIUTeTc) state->dataZoneEnergyDemand->ZoneSysEnergyDemand(1).RemainingOutputReqToHeatSP = -200.0; state->dataZoneEnergyDemand->ZoneSysEnergyDemand(2).RemainingOutputReqToCoolSP = -1100.0; state->dataZoneEnergyDemand->ZoneSysEnergyDemand(2).RemainingOutputReqToHeatSP = -1200.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(2); state->dataHVACVarRefFlow->CompOnMassFlow = 0.0; // system is off // Run and Check @@ -3767,6 +3771,7 @@ TEST_F(EnergyPlusFixture, VRFTest_SysCurve) state->dataSize->FinalZoneSizing(state->dataSize->CurZoneEqNum).DesHeatVolFlow = 0.566337; state->dataZoneEnergyDemand->ZoneSysEnergyDemand.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); ProcessScheduleInput(*state); // read schedules GetCurveInput(*state); // read curves @@ -4020,8 +4025,8 @@ TEST_F(EnergyPlusFixture, VRFTest_SysCurve) state->dataHeatBalFanSys->ZoneThermostatSetPointLo = 21.0; state->dataHeatBalFanSys->TempControlType.allocate(1); state->dataHeatBalFanSys->TempControlType = DataHVACGlobals::ThermostatType::DualSetPointWithDeadBand; - state->dataHeatBalFanSys->ZT.allocate(1); - state->dataHeatBalFanSys->ZT = 25.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZT = 25.0; state->dataLoopNodes->Node(state->dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneAirNode).Temp = 27.0; state->dataZoneEnergyDemand->ZoneSysEnergyDemand(CurZoneNum).RemainingOutputRequired = @@ -4124,7 +4129,7 @@ TEST_F(EnergyPlusFixture, VRFTest_SysCurve) } // ensure that TU turns off when fan heat exceeds the heating load - state->dataHeatBalFanSys->ZT = 20.0; // set zone temp below heating SP (SP=21) to ensure heating mode + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZT = 20.0; // set zone temp below heating SP (SP=21) to ensure heating mode state->dataLoopNodes->Node(state->dataHVACVarRefFlow->VRFTU(VRFTUNum).ZoneAirNode).Temp = 20.0; state->dataLoopNodes->Node(state->dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUInletNodeNum).Temp = 20; // 20 C at 13 C WB (44.5 % RH) for indoor heating condition @@ -4157,7 +4162,7 @@ TEST_F(EnergyPlusFixture, VRFTest_SysCurve) EXPECT_EQ(state->dataHVACVarRefFlow->VRF(VRFCond).VRFCondPLR, 0.0); // system should be off // ensure that TU operates when fan heat does not exceed the heating load - state->dataHeatBalFanSys->ZT = 20.0; // set zone temp below heating SP (SP=21) to ensure heating mode + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZT = 20.0; // set zone temp below heating SP (SP=21) to ensure heating mode state->dataLoopNodes->Node(state->dataHVACVarRefFlow->VRF(VRFCond).CondenserNodeNum).Temp = 19.0; // within the heating temperature range of VRF outdoor unit state->dataLoopNodes->Node(state->dataHVACVarRefFlow->VRFTU(VRFTUNum).VRFTUOAMixerOANodeNum).Temp = 19.0; @@ -4865,6 +4870,7 @@ TEST_F(EnergyPlusFixture, VRFTest_SysCurve_GetInputFailers) state->dataSize->FinalZoneSizing(state->dataSize->CurZoneEqNum).DesHeatVolFlow = 0.566337; state->dataZoneEnergyDemand->ZoneSysEnergyDemand.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); ProcessScheduleInput(*state); // read schedules GetCurveInput(*state); // read curves @@ -5715,6 +5721,7 @@ TEST_F(EnergyPlusFixture, VRFTest_SysCurve_WaterCooled) state->dataSize->FinalZoneSizing(state->dataSize->CurZoneEqNum).DesHeatVolFlow = 0.566337; state->dataZoneEnergyDemand->ZoneSysEnergyDemand.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); Array2D DummyArray; // Sky temperature state->dataGlobal->NumOfTimeStepInHour = 4; @@ -6635,6 +6642,7 @@ TEST_F(EnergyPlusFixture, VRFTest_TU_NoLoad_OAMassFlowRateTest) state->dataZoneEnergyDemand->ZoneSysEnergyDemand(CurZoneNum).RemainingOutputReqToCoolSP = 0.0; // No load state->dataZoneEnergyDemand->ZoneSysEnergyDemand(CurZoneNum).RemainingOutputReqToHeatSP = 0.0; // No load QZnReq = state->dataZoneEnergyDemand->ZoneSysEnergyDemand(CurZoneNum).RemainingOutputRequired; // No load + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); // Initialize terminal unit state->dataScheduleMgr->Schedule(state->dataHVACVarRefFlow->VRFTU(VRFTUNum).SchedPtr).CurrentValue = 1.0; // turn on TU state->dataScheduleMgr->Schedule(state->dataHVACVarRefFlow->VRFTU(VRFTUNum).FanAvailSchedPtr).CurrentValue = 1.0; // turn on fan @@ -11384,6 +11392,7 @@ TEST_F(EnergyPlusFixture, VRFTU_SysCurve_ReportOutputVerificationTest) state->dataSize->FinalZoneSizing(state->dataSize->CurZoneEqNum).DesHeatVolFlow = 0.566337; state->dataZoneEnergyDemand->ZoneSysEnergyDemand.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); ProcessScheduleInput(*state); GetCurveInput(*state); GetZoneData(*state, ErrorsFound); @@ -13119,6 +13128,7 @@ TEST_F(EnergyPlusFixture, VRF_FluidTCtrl_ReportOutputVerificationTest) state->dataSize->FinalZoneSizing(state->dataSize->CurZoneEqNum).DesHeatVolFlow = 0.566337; state->dataZoneEnergyDemand->ZoneSysEnergyDemand.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); ProcessScheduleInput(*state); GetCurveInput(*state); GetZoneData(*state, ErrorsFound); @@ -15188,6 +15198,7 @@ TEST_F(EnergyPlusFixture, VRFTest_TU_NotOnZoneHVACEquipmentList) state->dataZoneEnergyDemand->ZoneSysEnergyDemand(CurZoneNum).RemainingOutputReqToCoolSP = 0.0; // No load state->dataZoneEnergyDemand->ZoneSysEnergyDemand(CurZoneNum).RemainingOutputReqToHeatSP = 0.0; // No load QZnReq = state->dataZoneEnergyDemand->ZoneSysEnergyDemand(CurZoneNum).RemainingOutputRequired; // No load + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); // Initialize terminal unit state->dataScheduleMgr->Schedule(state->dataHVACVarRefFlow->VRFTU(VRFTUNum).FanOpModeSchedPtr).CurrentValue = 1.0; // set continuous fan operating mode @@ -15802,6 +15813,7 @@ TEST_F(EnergyPlusFixture, VRFTU_FanOnOff_Power) state->dataSize->FinalZoneSizing(state->dataSize->CurZoneEqNum).DesHeatVolFlow = 0.566337; state->dataZoneEnergyDemand->ZoneSysEnergyDemand.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); ProcessScheduleInput(*state); GetCurveInput(*state); GetZoneData(*state, ErrorsFound); diff --git a/tst/EnergyPlus/unit/HeatBalanceManager.unit.cc b/tst/EnergyPlus/unit/HeatBalanceManager.unit.cc index cb3bb010c60..447e9b220cf 100644 --- a/tst/EnergyPlus/unit/HeatBalanceManager.unit.cc +++ b/tst/EnergyPlus/unit/HeatBalanceManager.unit.cc @@ -80,6 +80,7 @@ #include #include #include +#include #include @@ -1255,7 +1256,7 @@ TEST_F(EnergyPlusFixture, HeatBalanceManager_TestZonePropertyLocalEnv) state->dataHeatBalSurf->SurfHConvInt(6) = 0.5; state->dataGlobal->KickOffSimulation = true; - state->dataHeatBalFanSys->ZoneLatentGain.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); state->dataGlobal->TimeStepZoneSec = 900; state->dataHeatBal->ZoneWinHeatGain.allocate(1); state->dataHeatBal->ZoneWinHeatGainRep.allocate(1); diff --git a/tst/EnergyPlus/unit/HeatBalanceMovableInsulation.unit.cc b/tst/EnergyPlus/unit/HeatBalanceMovableInsulation.unit.cc index 3f923ba1b83..493a36b20e1 100644 --- a/tst/EnergyPlus/unit/HeatBalanceMovableInsulation.unit.cc +++ b/tst/EnergyPlus/unit/HeatBalanceMovableInsulation.unit.cc @@ -96,8 +96,10 @@ TEST_F(EnergyPlusFixture, HeatBalanceMovableInsulation_EvalOutsideMovableInsulat state->dataMaterial->Material(1).ReflectSolBeamFront = 0.20; state->dataHeatBal->Zone.allocate(1); state->dataGlobal->NumOfZones = 1; - state->dataHeatBal->Zone(1).OpaqOrIntMassSurfaceFirst = 1; - state->dataHeatBal->Zone(1).OpaqOrIntMassSurfaceLast = 1; + state->dataHeatBal->space.allocate(1); + state->dataHeatBal->Zone(1).spaceIndexes.emplace_back(1); + state->dataHeatBal->space(1).OpaqOrIntMassSurfaceFirst = 1; + state->dataHeatBal->space(1).OpaqOrIntMassSurfaceLast = 1; state->dataHeatBalSurf->SurfAbsSolarExt(1) = 0.0; HeatBalanceSurfaceManager::EvalOutsideMovableInsulation(*state); @@ -145,8 +147,10 @@ TEST_F(EnergyPlusFixture, HeatBalanceMovableInsulation_EvalInsideMovableInsulati state->dataMaterial->Material(1).ReflectSolBeamFront = 0.20; state->dataHeatBal->Zone.allocate(1); state->dataGlobal->NumOfZones = 1; - state->dataHeatBal->Zone(1).OpaqOrIntMassSurfaceFirst = 1; - state->dataHeatBal->Zone(1).OpaqOrIntMassSurfaceLast = 1; + state->dataHeatBal->space.allocate(1); + state->dataHeatBal->Zone(1).spaceIndexes.emplace_back(1); + state->dataHeatBal->space(1).OpaqOrIntMassSurfaceFirst = 1; + state->dataHeatBal->space(1).OpaqOrIntMassSurfaceLast = 1; state->dataHeatBalSurf->SurfAbsSolarInt(1) = 0.0; HeatBalanceSurfaceManager::EvalInsideMovableInsulation(*state); diff --git a/tst/EnergyPlus/unit/HeatBalanceSurfaceManager.unit.cc b/tst/EnergyPlus/unit/HeatBalanceSurfaceManager.unit.cc index f536ea0aa20..99dd0be8d9d 100644 --- a/tst/EnergyPlus/unit/HeatBalanceSurfaceManager.unit.cc +++ b/tst/EnergyPlus/unit/HeatBalanceSurfaceManager.unit.cc @@ -83,6 +83,7 @@ #include #include #include +#include #include "Fixtures/EnergyPlusFixture.hh" @@ -153,12 +154,14 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_CalcOutsideSurfTemp) state->dataGlobal->HourOfDay = 1; state->dataGlobal->TimeStep = 1; - state->dataHeatBal->Zone(ZoneNum).HTSurfaceFirst = 1; - state->dataHeatBal->Zone(ZoneNum).HTSurfaceLast = 1; - state->dataHeatBal->Zone(ZoneNum).OpaqOrIntMassSurfaceFirst = 1; - state->dataHeatBal->Zone(ZoneNum).OpaqOrIntMassSurfaceLast = 1; - state->dataHeatBal->Zone(ZoneNum).OpaqOrWinSurfaceFirst = 1; - state->dataHeatBal->Zone(ZoneNum).OpaqOrWinSurfaceLast = 1; + state->dataHeatBal->space.allocate(1); + state->dataHeatBal->Zone(ZoneNum).spaceIndexes.emplace_back(ZoneNum); + state->dataHeatBal->space(ZoneNum).HTSurfaceFirst = 1; + state->dataHeatBal->space(ZoneNum).HTSurfaceLast = 1; + state->dataHeatBal->space(ZoneNum).OpaqOrIntMassSurfaceFirst = 1; + state->dataHeatBal->space(ZoneNum).OpaqOrIntMassSurfaceLast = 1; + state->dataHeatBal->space(ZoneNum).OpaqOrWinSurfaceFirst = 1; + state->dataHeatBal->space(ZoneNum).OpaqOrWinSurfaceLast = 1; CalcOutsideSurfTemp(*state, SurfNum, ZoneNum, ConstrNum, HMovInsul, TempExt, ErrorFlag); @@ -285,10 +288,10 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_ComputeIntThermalAbsorpFacto state->dataHeatBal->TotMaterials = 1; state->dataHeatBal->TotConstructs = 1; state->dataHeatBal->Zone.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBal->Zone(1).WindowSurfaceFirst = 1; - state->dataHeatBal->Zone(1).WindowSurfaceLast = 1; - state->dataHeatBal->Zone(1).zoneRadEnclosureFirst = 1; - state->dataHeatBal->Zone(1).zoneRadEnclosureLast = 1; + state->dataHeatBal->space.allocate(1); + state->dataHeatBal->Zone(1).spaceIndexes.emplace_back(1); + state->dataHeatBal->space(1).WindowSurfaceFirst = 1; + state->dataHeatBal->space(1).WindowSurfaceLast = 1; state->dataSurface->Surface.allocate(state->dataSurface->TotSurfaces); state->dataSurface->SurfaceWindow.allocate(state->dataSurface->TotSurfaces); SurfaceGeometry::AllocateSurfaceWindows(*state, state->dataSurface->TotSurfaces); @@ -308,6 +311,7 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_ComputeIntThermalAbsorpFacto state->dataViewFactor->NumOfRadiantEnclosures = 1; state->dataViewFactor->EnclRadInfo.allocate(1); state->dataViewFactor->EnclRadInfo(1).radReCalc = true; + state->dataViewFactor->EnclRadInfo(1).spaceNums.emplace_back(1); state->dataViewFactor->EnclRadInfo(1).SurfacePtr.allocate(1); state->dataViewFactor->EnclRadInfo(1).SurfacePtr(1) = 1; @@ -336,10 +340,12 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_UpdateFinalThermalHistories) state->dataSurface->Surface(1).HeatTransferAlgorithm = DataSurfaces::HeatTransferModel::CTF; state->dataSurface->Surface(1).ExtBoundCond = 1; state->dataSurface->Surface(1).Construction = 1; - state->dataHeatBal->Zone(1).OpaqOrIntMassSurfaceFirst = 1; - state->dataHeatBal->Zone(1).OpaqOrIntMassSurfaceLast = 1; - state->dataHeatBal->Zone(1).HTSurfaceFirst = 1; - state->dataHeatBal->Zone(1).HTSurfaceLast = 1; + state->dataHeatBal->space.allocate(1); + state->dataHeatBal->Zone(1).spaceIndexes.emplace_back(1); + state->dataHeatBal->space(1).OpaqOrIntMassSurfaceFirst = 1; + state->dataHeatBal->space(1).OpaqOrIntMassSurfaceLast = 1; + state->dataHeatBal->space(1).HTSurfaceFirst = 1; + state->dataHeatBal->space(1).HTSurfaceLast = 1; state->dataConstruction->Construct(1).NumCTFTerms = 2; state->dataConstruction->Construct(1).SourceSinkPresent = true; @@ -754,10 +760,6 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestSurfTempCalcHeatBalanceI state->dataSize->ZoneEqSizing.allocate(1); state->dataHeatBal->Zone(1).SystemZoneNodeNumber = 5; state->dataEnvrn->OutBaroPress = 101325.0; - state->dataHeatBalFanSys->MAT.allocate(1); // Zone temperature C - state->dataHeatBalFanSys->MAT(1) = 24.0; - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.001; state->dataLoopNodes->Node.allocate(4); @@ -793,10 +795,11 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestSurfTempCalcHeatBalanceI state->dataMstBal->HMassConvInFD.allocate(6); state->dataGlobal->BeginSimFlag = true; state->dataGlobal->KickOffSimulation = true; - state->dataHeatBalFanSys->ZoneLatentGain.allocate(1); state->dataGlobal->TimeStepZoneSec = 900; SolarShading::AllocateModuleArrays(*state); HeatBalanceManager::AllocateZoneHeatBalArrays(*state); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 24.0; AllocateSurfaceHeatBalArrays(*state); createFacilityElectricPowerServiceObject(*state); @@ -822,22 +825,6 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestSurfTempCalcHeatBalanceI EXPECT_EQ(24.0, state->dataHeatBal->SurfTempEffBulkAir(1)); EXPECT_EQ(23.0, state->dataHeatBal->SurfTempEffBulkAir(2)); EXPECT_EQ(24.0, state->dataHeatBal->SurfTempEffBulkAir(3)); - - state->dataZoneEquip->ZoneEquipConfig.deallocate(); - state->dataSize->ZoneEqSizing.deallocate(); - state->dataHeatBalFanSys->MAT.deallocate(); // Zone temperature C - state->dataHeatBalFanSys->ZoneAirHumRat.deallocate(); - state->dataLoopNodes->Node.deallocate(); - state->dataGlobal->KickOffSimulation = false; - state->dataHeatBalSurf->SurfTempInTmp.deallocate(); - state->dataHeatBalSurf->SurfHConvInt.deallocate(); - state->dataMstBal->HConvInFD.deallocate(); - state->dataMstBal->RhoVaporAirIn.deallocate(); - state->dataMstBal->HMassConvInFD.deallocate(); - state->dataHeatBalFanSys->ZoneLatentGain.deallocate(); - state->dataHeatBal->ZoneWinHeatGain.deallocate(); - state->dataHeatBal->ZoneWinHeatGainRep.deallocate(); - state->dataHeatBal->ZoneWinHeatGainRepEnergy.deallocate(); } TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestSurfTempCalcHeatBalanceInsideSurfKiva) @@ -1315,10 +1302,6 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestSurfTempCalcHeatBalanceI state->dataSize->ZoneEqSizing.allocate(1); state->dataHeatBal->Zone(1).SystemZoneNodeNumber = 5; state->dataEnvrn->OutBaroPress = 101325.0; - state->dataHeatBalFanSys->MAT.allocate(1); // Zone temperature C - state->dataHeatBalFanSys->MAT(1) = 24.0; - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.001; state->dataLoopNodes->Node.allocate(4); @@ -1362,13 +1345,14 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestSurfTempCalcHeatBalanceI state->dataGlobal->BeginSimFlag = true; state->dataGlobal->KickOffSimulation = true; - state->dataHeatBalFanSys->ZoneLatentGain.allocate(1); state->dataGlobal->TimeStepZoneSec = 900; state->dataHeatBalSurf->SurfWinCoeffAdjRatio.dimension(6, 1.0); AllocateSurfaceHeatBalArrays(*state); createFacilityElectricPowerServiceObject(*state); HeatBalanceManager::AllocateZoneHeatBalArrays(*state); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 24.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.001; SolarShading::AllocateModuleArrays(*state); SolarShading::DetermineShadowingCombinations(*state); for (int loop = 1; loop <= state->dataSurface->TotSurfaces; ++loop) { @@ -1843,10 +1827,9 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestSurfPropertyLocalEnv) state->dataSize->ZoneEqSizing.allocate(1); state->dataHeatBal->Zone(1).SystemZoneNodeNumber = 5; state->dataEnvrn->OutBaroPress = 101325.0; - state->dataHeatBalFanSys->MAT.allocate(1); // Zone temperature C - state->dataHeatBalFanSys->MAT(1) = 24.0; - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 24.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.001; state->dataLoopNodes->Node.allocate(4); @@ -1880,7 +1863,6 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestSurfPropertyLocalEnv) state->dataGlobal->BeginSimFlag = true; state->dataGlobal->KickOffSimulation = true; - state->dataHeatBalFanSys->ZoneLatentGain.allocate(1); state->dataGlobal->TimeStepZoneSec = 900; state->dataHeatBal->ZoneWinHeatGain.allocate(1); state->dataHeatBal->ZoneWinHeatGainRep.allocate(1); @@ -2422,10 +2404,9 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestSurfPropertySrdSurfLWR) state->dataSize->ZoneEqSizing.allocate(1); state->dataHeatBal->Zone(1).SystemZoneNodeNumber = 5; state->dataEnvrn->OutBaroPress = 101325.0; - state->dataHeatBalFanSys->MAT.allocate(1); // Zone temperature C - state->dataHeatBalFanSys->MAT(1) = 24.0; - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 24.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.001; state->dataLoopNodes->Node.allocate(4); @@ -2459,7 +2440,6 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestSurfPropertySrdSurfLWR) state->dataGlobal->BeginSimFlag = true; state->dataGlobal->KickOffSimulation = true; - state->dataHeatBalFanSys->ZoneLatentGain.allocate(1); state->dataGlobal->TimeStepZoneSec = 900; state->dataHeatBal->ZoneWinHeatGain.allocate(1); state->dataHeatBal->ZoneWinHeatGainRep.allocate(1); @@ -2996,10 +2976,9 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestSurfTempCalcHeatBalanceA state->dataSize->ZoneEqSizing.allocate(1); state->dataHeatBal->Zone(1).SystemZoneNodeNumber = 5; state->dataEnvrn->OutBaroPress = 101325.0; - state->dataHeatBalFanSys->MAT.allocate(1); // Zone temperature C - state->dataHeatBalFanSys->MAT(1) = 24.0; - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 24.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.001; state->dataLoopNodes->Node.allocate(4); @@ -3036,7 +3015,6 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestSurfTempCalcHeatBalanceA state->dataGlobal->BeginSimFlag = true; state->dataGlobal->KickOffSimulation = true; - state->dataHeatBalFanSys->ZoneLatentGain.allocate(1); state->dataGlobal->TimeStepZoneSec = 900; state->dataHeatBal->ZoneWinHeatGain.allocate(1); state->dataHeatBal->ZoneWinHeatGainRep.allocate(1); @@ -3068,23 +3046,6 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestSurfTempCalcHeatBalanceA EXPECT_EQ(-0.1, state->dataHeatBalSurf->SurfQAdditionalHeatSourceOutside(1)); CalcHeatBalanceInsideSurf(*state); EXPECT_EQ(0.1, state->dataHeatBalSurf->SurfQAdditionalHeatSourceInside(6)); - - state->dataZoneEquip->ZoneEquipConfig.deallocate(); - state->dataSize->ZoneEqSizing.deallocate(); - state->dataHeatBalFanSys->MAT.deallocate(); // Zone temperature C - state->dataHeatBalFanSys->ZoneAirHumRat.deallocate(); - state->dataLoopNodes->Node.deallocate(); - state->dataGlobal->KickOffSimulation = false; - state->dataHeatBalSurf->SurfTempInTmp.deallocate(); - state->dataHeatBal->SurfTempEffBulkAir.deallocate(); - state->dataHeatBalSurf->SurfHConvInt.deallocate(); - state->dataMstBal->HConvInFD.deallocate(); - state->dataMstBal->RhoVaporAirIn.deallocate(); - state->dataMstBal->HMassConvInFD.deallocate(); - state->dataHeatBalFanSys->ZoneLatentGain.deallocate(); - state->dataHeatBal->ZoneWinHeatGain.deallocate(); - state->dataHeatBal->ZoneWinHeatGainRep.deallocate(); - state->dataHeatBal->ZoneWinHeatGainRepEnergy.deallocate(); } TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestReportIntMovInsInsideSurfTemp) @@ -3227,8 +3188,9 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestResilienceMetricReport) state->dataHeatBal->Zone.allocate(state->dataGlobal->NumOfZones); state->dataHeatBal->Resilience.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->ZTAV.dimension(state->dataGlobal->NumOfZones, 0.0); - state->dataHeatBalFanSys->ZoneAirHumRatAvg.dimension(state->dataGlobal->NumOfZones, 0.0); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(state->dataGlobal->NumOfZones); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 0.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvg = 0.0; state->dataHeatBalFanSys->ZoneThermostatSetPointLo.dimension(state->dataGlobal->NumOfZones, 22.0); state->dataHeatBalFanSys->ZoneThermostatSetPointHi.dimension(state->dataGlobal->NumOfZones, 28.0); @@ -3253,9 +3215,9 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestResilienceMetricReport) // Heat Index Case 1: Zone T < 80 F; state->dataGlobal->HourOfDay = 1; - state->dataHeatBalFanSys->ZTAV(1) = 25; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 25; state->dataThermalComforts->ThermalComfortData(1).FangerPMV = -4.0; - state->dataHeatBalFanSys->ZoneAirHumRatAvg(1) = 0.00988; // RH = 50% + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvg = 0.00988; // RH = 50% CalcThermalResilience(*state); ReportThermalResilience(*state); EXPECT_NEAR(25, state->dataHeatBal->Resilience(1).ZoneHeatIndex, 0.5); @@ -3263,8 +3225,8 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestResilienceMetricReport) // Heat Index Case 2: Zone RH > 85, 80 < T < 87 F; state->dataGlobal->HourOfDay = 2; - state->dataHeatBalFanSys->ZTAV(1) = 27; - state->dataHeatBalFanSys->ZoneAirHumRatAvg(1) = 0.02035; // RH = 90% + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 27; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvg = 0.02035; // RH = 90% CalcThermalResilience(*state); ReportThermalResilience(*state); EXPECT_NEAR(31, state->dataHeatBal->Resilience(1).ZoneHeatIndex, 0.5); @@ -3272,8 +3234,8 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestResilienceMetricReport) // Heat Index Case 3: < Zone RH > 85, 80 < T < 87 F; state->dataGlobal->HourOfDay = 3; - state->dataHeatBalFanSys->ZTAV(1) = 27; - state->dataHeatBalFanSys->ZoneAirHumRatAvg(1) = 0.0022; // RH = 10% + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 27; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvg = 0.0022; // RH = 10% CalcThermalResilience(*state); ReportThermalResilience(*state); EXPECT_NEAR(26, state->dataHeatBal->Resilience(1).ZoneHeatIndex, 0.5); @@ -3281,8 +3243,8 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestResilienceMetricReport) // Heat Index Case 4: Rothfusz regression, other than the above conditions; state->dataGlobal->HourOfDay = 4; - state->dataHeatBalFanSys->ZTAV(1) = 30; - state->dataHeatBalFanSys->ZoneAirHumRatAvg(1) = 0.01604; // RH = 60% + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 30; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvg = 0.01604; // RH = 60% CalcThermalResilience(*state); ReportThermalResilience(*state); EXPECT_NEAR(33, state->dataHeatBal->Resilience(1).ZoneHeatIndex, 0.5); @@ -3446,7 +3408,7 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestResilienceMetricReport) state->dataThermalComforts->ThermalComfortData(1).PierceSET = 11.2; state->dataScheduleMgr->Schedule(1).CurrentValue = 0.4; - state->dataHeatBalFanSys->ZTAV(1) = 31; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 31; state->dataThermalComforts->ThermalComfortData(1).FangerPMV = -3.5; for (int hour = 5; hour <= 7; hour++) { state->dataGlobal->HourOfDay = hour; @@ -3495,7 +3457,7 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestResilienceMetricReport) EXPECT_NEAR(0.0, state->dataHeatBal->Resilience(1).ZoneDiscomfortWtExceedOccupiedHourBins[3], 1e-8); // Very-hot Exceedance OccupiedHours state->dataThermalComforts->ThermalComfortData(1).PierceSET = 32; - state->dataHeatBalFanSys->ZTAV(1) = 28; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 28; state->dataScheduleMgr->Schedule(1).CurrentValue = 1.0; state->dataThermalComforts->ThermalComfortData(1).FangerPMV = -1.2; for (int hour = 8; hour <= 10; hour++) { @@ -3544,7 +3506,7 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestResilienceMetricReport) EXPECT_NEAR(0.0, state->dataHeatBal->Resilience(1).ZoneDiscomfortWtExceedOccupiedHourBins[3], 1e-8); // Very-hot Exceedance OccupiedHours state->dataThermalComforts->ThermalComfortData(1).PierceSET = 25; - state->dataHeatBalFanSys->ZTAV(1) = 31; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 31; state->dataThermalComforts->ThermalComfortData(1).FangerPMV = 0.5; for (int hour = 11; hour <= 12; hour++) { state->dataGlobal->HourOfDay = hour; @@ -3591,7 +3553,7 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestResilienceMetricReport) EXPECT_NEAR(0.0, state->dataHeatBal->Resilience(1).ZoneDiscomfortWtExceedOccupiedHourBins[3], 1e-8); // Very-hot Exceedance OccupiedHours state->dataThermalComforts->ThermalComfortData(1).PierceSET = 11.2; - state->dataHeatBalFanSys->ZTAV(1) = 30; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 30; state->dataScheduleMgr->Schedule(1).CurrentValue = 0.4; state->dataThermalComforts->ThermalComfortData(1).FangerPMV = 1.2; for (int hour = 13; hour <= 18; hour++) { @@ -3640,7 +3602,7 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestResilienceMetricReport) EXPECT_NEAR(0.0, state->dataHeatBal->Resilience(1).ZoneDiscomfortWtExceedOccupiedHourBins[3], 1e-8); // Very-hot Exceedance OccupiedHours state->dataScheduleMgr->Schedule(1).CurrentValue = 0; - state->dataHeatBalFanSys->ZTAV(1) = 12; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 12; state->dataThermalComforts->ThermalComfortData(1).FangerPMV = 1.2; for (int hour = 19; hour <= 20; hour++) { state->dataGlobal->HourOfDay = hour; @@ -3772,8 +3734,9 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestThermalResilienceReportR state->dataHeatBal->Zone.allocate(state->dataGlobal->NumOfZones); state->dataHeatBal->Resilience.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->ZTAV.dimension(state->dataGlobal->NumOfZones, 0.0); - state->dataHeatBalFanSys->ZoneAirHumRatAvg.dimension(state->dataGlobal->NumOfZones, 0.0); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(state->dataGlobal->NumOfZones); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 0.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvg = 0.0; state->dataHeatBal->Zone.allocate(state->dataGlobal->NumOfZones); state->dataHeatBalFanSys->ZoneThermostatSetPointLo.dimension(state->dataGlobal->NumOfZones, 22.0); @@ -3834,9 +3797,9 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestThermalResilienceReportR // --------------------------------------------------------------------- // Heat Index Case 1: Zone T < 80 F; state->dataGlobal->HourOfDay = 1; - state->dataHeatBalFanSys->ZTAV(1) = 25; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 25; state->dataThermalComforts->ThermalComfortData(1).FangerPMV = -4.0; - state->dataHeatBalFanSys->ZoneAirHumRatAvg(1) = 0.00988; // RH = 50% + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvg = 0.00988; // RH = 50% CalcThermalResilience(*state); ReportThermalResilience(*state); EXPECT_NEAR(25, state->dataHeatBal->Resilience(1).ZoneHeatIndex, 0.5); @@ -3844,8 +3807,8 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestThermalResilienceReportR // Heat Index Case 2: Zone RH > 85, 80 < T < 87 F; state->dataGlobal->HourOfDay = 2; - state->dataHeatBalFanSys->ZTAV(1) = 27; - state->dataHeatBalFanSys->ZoneAirHumRatAvg(1) = 0.02035; // RH = 90% + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 27; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvg = 0.02035; // RH = 90% CalcThermalResilience(*state); ReportThermalResilience(*state); EXPECT_NEAR(31, state->dataHeatBal->Resilience(1).ZoneHeatIndex, 0.5); @@ -3853,8 +3816,8 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestThermalResilienceReportR // Heat Index Case 3: < Zone RH > 85, 80 < T < 87 F; state->dataGlobal->HourOfDay = 3; - state->dataHeatBalFanSys->ZTAV(1) = 27; - state->dataHeatBalFanSys->ZoneAirHumRatAvg(1) = 0.0022; // RH = 10% + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 27; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvg = 0.0022; // RH = 10% CalcThermalResilience(*state); ReportThermalResilience(*state); EXPECT_NEAR(26, state->dataHeatBal->Resilience(1).ZoneHeatIndex, 0.5); @@ -3862,8 +3825,8 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestThermalResilienceReportR // Heat Index Case 4: Rothfusz regression, other than the above conditions; state->dataGlobal->HourOfDay = 4; - state->dataHeatBalFanSys->ZTAV(1) = 30; - state->dataHeatBalFanSys->ZoneAirHumRatAvg(1) = 0.01604; // RH = 60% + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 30; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvg = 0.01604; // RH = 60% CalcThermalResilience(*state); ReportThermalResilience(*state); EXPECT_NEAR(33, state->dataHeatBal->Resilience(1).ZoneHeatIndex, 0.5); @@ -3990,7 +3953,7 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestThermalResilienceReportR state->dataThermalComforts->ThermalComfortData(1).PierceSET = 11.2; state->dataScheduleMgr->Schedule(1).CurrentValue = 0.4; - state->dataHeatBalFanSys->ZTAV(1) = 31; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 31; state->dataThermalComforts->ThermalComfortData(1).FangerPMV = -3.5; for (int hour = 5; hour <= 7; hour++) { state->dataGlobal->HourOfDay = hour; @@ -4041,7 +4004,7 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestThermalResilienceReportR EXPECT_NEAR(0.0, state->dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(1, 1)[3], 1e-8); // Very-hot Exceedance OccupiedHours state->dataThermalComforts->ThermalComfortData(1).PierceSET = 32; - state->dataHeatBalFanSys->ZTAV(1) = 28; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 28; state->dataScheduleMgr->Schedule(1).CurrentValue = 1.0; state->dataThermalComforts->ThermalComfortData(1).FangerPMV = -1.2; for (int hour = 8; hour <= 10; hour++) { @@ -4096,7 +4059,7 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestThermalResilienceReportR // --------------------------------------------------------------------- state->dataThermalComforts->ThermalComfortData(1).PierceSET = 25; - state->dataHeatBalFanSys->ZTAV(1) = 31; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 31; state->dataThermalComforts->ThermalComfortData(1).FangerPMV = 0.5; for (int hour = 11; hour <= 12; hour++) { state->dataGlobal->HourOfDay = hour; @@ -4108,7 +4071,7 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestThermalResilienceReportR // --------------------------------------------------------------------- state->dataThermalComforts->ThermalComfortData(1).PierceSET = 11.2; - state->dataHeatBalFanSys->ZTAV(1) = 30; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 30; state->dataScheduleMgr->Schedule(1).CurrentValue = 0.4; state->dataThermalComforts->ThermalComfortData(1).FangerPMV = 1.2; for (int hour = 13; hour <= 18; hour++) { @@ -4159,7 +4122,7 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestThermalResilienceReportR EXPECT_NEAR(0.0, state->dataHeatBalFanSys->ZoneDiscomfortWtExceedOccupiedHourBinsRepPeriod(1, 2)[3], 1e-8); // Very-hot Exceedance OccupiedHours state->dataScheduleMgr->Schedule(1).CurrentValue = 0; - state->dataHeatBalFanSys->ZTAV(1) = 12; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 12; state->dataThermalComforts->ThermalComfortData(1).FangerPMV = 1.2; for (int hour = 19; hour <= 20; hour++) { state->dataGlobal->HourOfDay = hour; @@ -4850,8 +4813,7 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestInitHBInterzoneWindow) HeatBalanceIntRadExchange::InitSolarViewFactors(*state); EXPECT_FALSE(has_err_output(true)); - state->dataHeatBalFanSys->MAT.allocate(1); // Zone temperature C - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); state->dataHeatBalSurf->SurfTempInTmp.allocate(6); @@ -4862,7 +4824,6 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestInitHBInterzoneWindow) state->dataGlobal->BeginSimFlag = true; state->dataGlobal->KickOffSimulation = true; - state->dataHeatBalFanSys->ZoneLatentGain.allocate(1); state->dataGlobal->TimeStepZoneSec = 900; state->dataHeatBal->ZoneWinHeatGain.allocate(1); state->dataHeatBal->ZoneWinHeatGainRep.allocate(1); @@ -5322,8 +5283,7 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestInitHBDaylightingNoExtWi SurfaceGeometry::SetupZoneGeometry(*state, ErrorsFound); EXPECT_FALSE(ErrorsFound); - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); state->dataHeatBalSurf->SurfTempInTmp.allocate(6); @@ -5334,7 +5294,6 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestInitHBDaylightingNoExtWi state->dataGlobal->BeginSimFlag = true; state->dataGlobal->KickOffSimulation = true; - state->dataHeatBalFanSys->ZoneLatentGain.allocate(1); state->dataGlobal->TimeStepZoneSec = 900; state->dataGlobal->NumOfTimeStepInHour = 6; state->dataGlobal->HourOfDay = 1; @@ -5954,15 +5913,12 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestTDDSurfWinHeatGain) state->dataHeatBal->Zone(1).SystemZoneNodeNumber = 5; state->dataHeatBal->Zone(2).SystemZoneNodeNumber = 10; state->dataEnvrn->OutBaroPress = 101325.0; - state->dataHeatBalFanSys->MAT.allocate(2); // Zone temperature C - state->dataHeatBalFanSys->MAT(1) = 24.0; - state->dataHeatBalFanSys->MAT(2) = 24.0; - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(2); - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.001; - state->dataHeatBalFanSys->ZoneAirHumRat(2) = 0.001; - state->dataHeatBalFanSys->ZoneAirHumRatAvg.allocate(2); - state->dataHeatBalFanSys->ZoneAirHumRatAvg(1) = 0.001; - state->dataHeatBalFanSys->ZoneAirHumRatAvg(2) = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(2); + for (auto &thisZoneHB : state->dataZoneTempPredictorCorrector->zoneHeatBalance) { + thisZoneHB.MAT = 24.0; + thisZoneHB.ZoneAirHumRat = 0.001; + thisZoneHB.ZoneAirHumRatAvg = 0.001; + } state->dataLoopNodes->Node.allocate(4); @@ -7076,10 +7032,10 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestSurfPropertySurfToGndLWR zoneEquipConfig.FixedReturnFlow.allocate(1); state->dataSize->ZoneEqSizing.allocate(1); - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->MAT(1) = 24.0; - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 24.0; + + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.001; state->dataLoopNodes->Node.allocate(4); auto &InletNode1 = state->dataLoopNodes->Node(1); @@ -7099,7 +7055,6 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestSurfPropertySurfToGndLWR state->dataHeatBal->ZoneWinHeatGain.allocate(1); state->dataHeatBal->ZoneWinHeatGainRep.allocate(1); state->dataHeatBal->ZoneWinHeatGainRepEnergy.allocate(1); - state->dataHeatBalFanSys->ZoneLatentGain.allocate(1); state->dataSurface->TotSurfaces = 6; // set convective coefficient adjustment ratio to 1.0 @@ -8321,10 +8276,9 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestSurfPropertyViewFactorsR zoneEquipConfig.FixedReturnFlow.allocate(1); state->dataSize->ZoneEqSizing.allocate(1); - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->MAT(1) = 24.0; - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 24.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.001; state->dataLoopNodes->Node.allocate(4); auto &InletNode1 = state->dataLoopNodes->Node(1); @@ -8344,7 +8298,6 @@ TEST_F(EnergyPlusFixture, HeatBalanceSurfaceManager_TestSurfPropertyViewFactorsR state->dataHeatBal->ZoneWinHeatGain.allocate(1); state->dataHeatBal->ZoneWinHeatGainRep.allocate(1); state->dataHeatBal->ZoneWinHeatGainRepEnergy.allocate(1); - state->dataHeatBalFanSys->ZoneLatentGain.allocate(1); state->dataSurface->TotSurfaces = 6; // set convective coefficient adjustment ratio to 1.0 diff --git a/tst/EnergyPlus/unit/HybridModel.unit.cc b/tst/EnergyPlus/unit/HybridModel.unit.cc index 94ff7606903..0f63f4df962 100644 --- a/tst/EnergyPlus/unit/HybridModel.unit.cc +++ b/tst/EnergyPlus/unit/HybridModel.unit.cc @@ -97,40 +97,21 @@ using namespace EnergyPlus::DataRoomAirModel; using namespace EnergyPlus::HybridModel; using namespace EnergyPlus::DataPrecisionGlobals; -TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneAirTempTest) +TEST_F(EnergyPlusFixture, HybridModel_correctZoneAirTempsTest) { // ZoneTempPredictorCorrector variable initialization state->dataHeatBal->Zone.allocate(1); state->dataHybridModel->HybridModelZone.allocate(1); + state->dataHybridModel->FlagHybridModel = true; state->dataRoomAirMod->AirModel.allocate(1); - state->dataHeatBalFanSys->ZTM1.allocate(1); - state->dataHeatBalFanSys->ZTM2.allocate(1); - state->dataHeatBalFanSys->ZTM3.allocate(1); - state->dataHeatBalFanSys->XMAT.allocate(1); - state->dataHeatBalFanSys->XM2T.allocate(1); - state->dataHeatBalFanSys->XM3T.allocate(1); state->dataRoomAirMod->ZTOC.allocate(1); state->dataRoomAirMod->ZTMX.allocate(1); state->dataRoomAirMod->ZTM1MX.allocate(1); - state->dataHeatBalFanSys->WZoneTimeMinus1Temp.allocate(1); - state->dataHeatBalFanSys->WZoneTimeMinus2Temp.allocate(1); - state->dataHeatBalFanSys->WZoneTimeMinus3Temp.allocate(1); - state->dataHeatBalFanSys->WZoneTimeMinus1.allocate(1); - state->dataHeatBalFanSys->WZoneTimeMinus2.allocate(1); - state->dataHeatBalFanSys->WZoneTimeMinus3.allocate(1); - state->dataHeatBalFanSys->AIRRAT.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); - state->dataHeatBalFanSys->NonAirSystemResponse.allocate(1); - state->dataHeatBalFanSys->NonAirSystemResponse(1) = 0.0; - state->dataHeatBalFanSys->SysDepZoneLoadsLagged.allocate(1); - state->dataHeatBalFanSys->SysDepZoneLoadsLagged(1) = 0.0; state->afn->exchangeData.allocate(1); state->dataLoopNodes->Node.allocate(1); state->dataHeatBalFanSys->TempTstatAir.allocate(1); state->dataHeatBalFanSys->LoadCorrectionFactor.allocate(1); - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->ZT.allocate(1); state->dataHeatBalFanSys->PreviousMeasuredZT1.allocate(1); state->dataHeatBalFanSys->PreviousMeasuredZT2.allocate(1); state->dataHeatBalFanSys->PreviousMeasuredZT3.allocate(1); @@ -140,38 +121,13 @@ TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneAirTempTest) state->dataScheduleMgr->Schedule.allocate(6); // CalcZoneComponentLoadSums variable initialization - state->dataHeatBalFanSys->MCPI.allocate(1); - state->dataHeatBalFanSys->MCPI(1) = 0.0; - state->dataHeatBalFanSys->MCPV.allocate(1); - state->dataHeatBalFanSys->MCPM.allocate(1); - state->dataHeatBalFanSys->MCPM(1) = 0.0; - state->dataHeatBalFanSys->MCPE.allocate(1); - state->dataHeatBalFanSys->MCPE(1) = 0.0; - state->dataHeatBalFanSys->MCPC.allocate(1); - state->dataHeatBalFanSys->MCPC(1) = 0.0; - state->dataHeatBalFanSys->MDotCPOA.allocate(1); - state->dataHeatBalFanSys->MDotCPOA(1) = 0.0; - state->dataHeatBalFanSys->MDotOA.allocate(1); - state->dataHeatBalFanSys->MDotOA(1) = 0.0; - state->dataHeatBalFanSys->MCPTI.allocate(1); - state->dataHeatBalFanSys->MCPTI(1) = 0.0; - state->dataHeatBalFanSys->MCPTV.allocate(1); - state->dataHeatBalFanSys->MCPTM.allocate(1); - state->dataHeatBalFanSys->MCPTM(1) = 0.0; - state->dataHeatBalFanSys->MCPTE.allocate(1); - state->dataHeatBalFanSys->MCPTE(1) = 0.0; - state->dataHeatBalFanSys->MCPTC.allocate(1); - state->dataHeatBalFanSys->MCPTC(1) = 0.0; state->dataSurface->SurfaceWindow.allocate(1); state->dataSurface->Surface.allocate(2); state->dataHeatBalSurf->SurfHConvInt.allocate(1); - state->dataHeatBal->ZoneSNLoadHeatRate.allocate(1); - state->dataHeatBal->ZoneSNLoadCoolRate.allocate(1); - state->dataHeatBal->ZoneSNLoadHeatEnergy.allocate(1); - state->dataHeatBal->ZoneSNLoadCoolEnergy.allocate(1); - state->dataZoneTempPredictorCorrector->ZoneAirRelHum.allocate(1); + state->dataZoneEnergyDemand->ZoneSysEnergyDemand.allocate(1); state->dataRoomAirMod->IsZoneDV.dimension(1, false); state->dataRoomAirMod->IsZoneCV.dimension(1, false); + state->dataRoomAirMod->IsZoneCV.dimension(1, false); state->dataRoomAirMod->IsZoneUI.dimension(1, false); state->dataRoomAirMod->ZoneDVMixedFlag.allocate(1); state->dataHeatBal->ZnAirRpt.allocate(1); @@ -180,40 +136,20 @@ TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneAirTempTest) state->dataSize->ZoneEqSizing.allocate(1); // CorrectZoneHumRat variable initialization - state->dataHeatBalFanSys->ZoneLatentGain.allocate(1); - state->dataHeatBalFanSys->ZoneLatentGain(1) = 0.0; - state->dataHeatBalFanSys->ZoneLatentGainExceptPeople.allocate(1); - state->dataHeatBalFanSys->ZoneLatentGainExceptPeople(1) = 0.0; state->dataHeatBalFanSys->SumLatentHTRadSys.allocate(1); state->dataHeatBalFanSys->SumLatentHTRadSys(1) = 0.0; - state->dataHeatBalFanSys->SumHmARaW.allocate(1); - state->dataHeatBalFanSys->SumHmARaW(1) = 0.0; state->dataHeatBalFanSys->SumConvHTRadSys.allocate(1); state->dataHeatBalFanSys->SumConvHTRadSys(1) = 0.0; state->dataHeatBalFanSys->SumConvPool.allocate(1); state->dataHeatBalFanSys->SumConvPool(1) = 0.0; - state->dataHeatBalFanSys->SumHmARa.allocate(1); - state->dataHeatBalFanSys->SumHmARa(1) = 0.0; - state->dataHeatBalFanSys->MixingMassFlowXHumRat.allocate(1); - state->dataHeatBalFanSys->MixingMassFlowXHumRat(1) = 0.0; - state->dataHeatBalFanSys->MixingMassFlowZone.allocate(1); - state->dataHeatBalFanSys->MixingMassFlowZone(1) = 0.0; - state->dataHeatBalFanSys->ZoneW1.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRatTemp.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->spaceHeatBalance.allocate(1); + auto &thisZoneHB = state->dataZoneTempPredictorCorrector->zoneHeatBalance(1); + thisZoneHB.MixingMassFlowXHumRat = 0.0; + thisZoneHB.MixingMassFlowZone = 0.0; + thisZoneHB.ZT = 0.0; state->dataHeatBalFanSys->SumLatentPool.allocate(1); state->dataHeatBalFanSys->SumLatentPool(1) = 0.0; - state->dataHeatBalFanSys->OAMFL.allocate(1); - state->dataHeatBalFanSys->OAMFL(1) = 0.0; - state->dataHeatBalFanSys->VAMFL.allocate(1); - state->dataHeatBalFanSys->VAMFL(1) = 0.0; - state->dataHeatBalFanSys->EAMFL.allocate(1); - state->dataHeatBalFanSys->EAMFL(1) = 0.0; - state->dataHeatBalFanSys->EAMFLxHumRat.allocate(1); - state->dataHeatBalFanSys->EAMFLxHumRat(1) = 0.0; - state->dataHeatBalFanSys->CTMFL.allocate(1); - state->dataHeatBalFanSys->CTMFL(1) = 0.0; - state->dataHeatBalFanSys->ZT.allocate(1); - state->dataHeatBalFanSys->ZT(1) = 0.0; // CorrectZoneContaminants variable initialization state->dataContaminantBalance->AZ.allocate(1); @@ -241,8 +177,11 @@ TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneAirTempTest) state->dataHeatBal->Zone(1).IsControlled = true; state->dataHeatBal->Zone(1).Multiplier = 1; state->dataHeatBal->Zone(1).SystemZoneNodeNumber = 1; - state->dataHeatBal->Zone(1).HTSurfaceFirst = 0; // No HT surface here. - state->dataHeatBal->Zone(1).HTSurfaceLast = -1; + state->dataHeatBal->space.allocate(1); + state->dataHeatBal->spaceIntGainDevices.allocate(1); + state->dataHeatBal->Zone(1).spaceIndexes.emplace_back(1); + state->dataHeatBal->space(1).HTSurfaceFirst = 0; + state->dataHeatBal->space(1).HTSurfaceLast = -1; state->dataHeatBal->Zone(1).Volume = 1061.88; state->dataGlobal->TimeStepZone = 10.0 / 60.0; // Zone timestep in hours state->dataHVACGlobal->TimeStepSys = 10.0 / 60.0; @@ -265,17 +204,17 @@ TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneAirTempTest) state->dataHybridModel->HybridModelZone(1).PeopleCountCalc_C = false; state->dataHybridModel->HybridModelZone(1).HybridStartDayOfYear = 1; state->dataHybridModel->HybridModelZone(1).HybridEndDayOfYear = 2; - state->dataHeatBalFanSys->MAT(1) = 0.0; + thisZoneHB.MAT = 0.0; state->dataHeatBalFanSys->PreviousMeasuredZT1(1) = 0.1; state->dataHeatBalFanSys->PreviousMeasuredZT2(1) = 0.2; state->dataHeatBalFanSys->PreviousMeasuredZT3(1) = 0.3; state->dataHeatBal->Zone(1).OutDryBulbTemp = -5.21; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.002083; - state->dataHeatBalFanSys->MCPV(1) = 1414.60; // Assign TempDepCoef - state->dataHeatBalFanSys->MCPTV(1) = -3335.10; // Assign TempIndCoef + thisZoneHB.ZoneAirHumRat = 0.002083; + thisZoneHB.MCPV = 1414.60; // Assign TempDepCoef + thisZoneHB.MCPTV = -3335.10; // Assign TempIndCoef state->dataEnvrn->OutBaroPress = 99166.67; - CorrectZoneAirTemp(*state, ZoneTempChange, true); + ZoneTempChange = correctZoneAirTemps(*state, true); EXPECT_NEAR(15.13, state->dataHeatBal->Zone(1).ZoneVolCapMultpSensHM, 0.01); // Case 2: Hybrid model infiltration with measured temperature (free-floating) @@ -289,18 +228,18 @@ TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneAirTempTest) state->dataHybridModel->HybridModelZone(1).PeopleCountCalc_C = false; state->dataHybridModel->HybridModelZone(1).HybridStartDayOfYear = 1; state->dataHybridModel->HybridModelZone(1).HybridEndDayOfYear = 2; - state->dataHeatBalFanSys->MAT(1) = 0.0; + thisZoneHB.MAT = 0.0; state->dataHeatBalFanSys->PreviousMeasuredZT1(1) = 0.02; state->dataHeatBalFanSys->PreviousMeasuredZT2(1) = 0.04; state->dataHeatBalFanSys->PreviousMeasuredZT3(1) = 0.06; state->dataHeatBal->Zone(1).ZoneVolCapMultpSens = 8.0; state->dataHeatBal->Zone(1).OutDryBulbTemp = -6.71; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.002083; - state->dataHeatBalFanSys->MCPV(1) = 539.49; // Assign TempDepCoef - state->dataHeatBalFanSys->MCPTV(1) = 270.10; // Assign TempIndCoef + thisZoneHB.ZoneAirHumRat = 0.002083; + thisZoneHB.MCPV = 539.49; // Assign TempDepCoef + thisZoneHB.MCPTV = 270.10; // Assign TempIndCoef state->dataEnvrn->OutBaroPress = 99250; - CorrectZoneAirTemp(*state, ZoneTempChange, true); + ZoneTempChange = correctZoneAirTemps(*state, true); EXPECT_NEAR(0.2444, state->dataHeatBal->Zone(1).InfilOAAirChangeRateHM, 0.01); // Case 3: Hybrid model infiltration with measured humidity ratio (free-floating) @@ -317,19 +256,19 @@ TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneAirTempTest) state->dataHeatBal->Zone(1).Volume = 4000; state->dataHeatBal->Zone(1).OutDryBulbTemp = -10.62; state->dataHeatBal->Zone(1).ZoneVolCapMultpMoist = 1.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.001120003; - state->dataHeatBalFanSys->ZT(1) = -6.08; + thisZoneHB.ZoneAirHumRat = 0.001120003; + thisZoneHB.ZT = -6.08; state->dataEnvrn->OutHumRat = 0.0011366887816818931; state->dataHeatBalFanSys->PreviousMeasuredHumRat1(1) = 0.0011186324286; state->dataHeatBalFanSys->PreviousMeasuredHumRat2(1) = 0.0011172070768; state->dataHeatBalFanSys->PreviousMeasuredHumRat3(1) = 0.0011155109625; state->dataHybridModel->HybridModelZone(1).ZoneMeasuredHumidityRatioSchedulePtr = 1; state->dataScheduleMgr->Schedule(state->dataHybridModel->HybridModelZone(1).ZoneMeasuredHumidityRatioSchedulePtr).CurrentValue = 0.001120003; - state->dataHeatBalFanSys->MCPV(1) = 539.49; - state->dataHeatBalFanSys->MCPTV(1) = 270.10; + thisZoneHB.MCPV = 539.49; + thisZoneHB.MCPTV = 270.10; state->dataEnvrn->OutBaroPress = 99500; - CorrectZoneHumRat(*state, 1); + thisZoneHB.correctHumRat(*state, 1); EXPECT_NEAR(0.5, state->dataHeatBal->Zone(1).InfilOAAirChangeRateHM, 0.01); // Case 4: Hybrid model people count with measured temperature (free-floating) @@ -344,20 +283,20 @@ TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneAirTempTest) state->dataHybridModel->HybridModelZone(1).HybridStartDayOfYear = 1; state->dataHybridModel->HybridModelZone(1).HybridEndDayOfYear = 2; - state->dataHeatBalFanSys->MAT(1) = -2.89; + thisZoneHB.MAT = -2.89; state->dataHeatBalFanSys->PreviousMeasuredZT1(1) = -2.887415174; state->dataHeatBalFanSys->PreviousMeasuredZT2(1) = -2.897557416; state->dataHeatBalFanSys->PreviousMeasuredZT3(1) = -2.909294101; state->dataHeatBal->Zone(1).ZoneVolCapMultpSens = 1.0; state->dataHeatBal->Zone(1).OutDryBulbTemp = -6.71; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.0024964; + thisZoneHB.ZoneAirHumRat = 0.0024964; state->dataEnvrn->OutBaroPress = 98916.7; - state->dataHeatBalFanSys->MCPV(1) = 5163.5; // Assign TempDepCoef - state->dataHeatBalFanSys->MCPTV(1) = -15956.8; // Assign TempIndCoef + thisZoneHB.MCPV = 5163.5; // Assign TempDepCoef + thisZoneHB.MCPTV = -15956.8; // Assign TempIndCoef state->dataHybridModel->HybridModelZone(1).ZoneMeasuredTemperatureSchedulePtr = 1; state->dataScheduleMgr->Schedule(state->dataHybridModel->HybridModelZone(1).ZoneMeasuredTemperatureSchedulePtr).CurrentValue = -2.923892218; - CorrectZoneAirTemp(*state, ZoneTempChange, true); + ZoneTempChange = correctZoneAirTemps(*state, true); EXPECT_NEAR(0, state->dataHeatBal->Zone(1).NumOccHM, 0.1); // Need to initialize SumIntGain // Case 5: Hybrid model people count with measured humidity ratio (free-floating) @@ -374,13 +313,13 @@ TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneAirTempTest) state->dataHeatBal->Zone(1).Volume = 4000; state->dataHeatBal->Zone(1).OutDryBulbTemp = -10.62; state->dataHeatBal->Zone(1).ZoneVolCapMultpMoist = 1.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.0024964; - state->dataHeatBalFanSys->ZT(1) = -2.92; + thisZoneHB.ZoneAirHumRat = 0.0024964; + thisZoneHB.ZT = -2.92; state->dataEnvrn->OutHumRat = 0.0025365002784602363; state->dataEnvrn->OutBaroPress = 98916.7; - state->dataHeatBalFanSys->OAMFL(1) = 0.700812; - state->dataHeatBalFanSys->ZoneLatentGain(1) = 211.2; - state->dataHeatBalFanSys->ZoneLatentGainExceptPeople(1) = 0.0; + thisZoneHB.OAMFL = 0.700812; + thisZoneHB.ZoneLatentGain = 211.2; + thisZoneHB.ZoneLatentGainExceptPeople = 0.0; state->dataHeatBalFanSys->PreviousMeasuredHumRat1(1) = 0.002496356; state->dataHeatBalFanSys->PreviousMeasuredHumRat2(1) = 0.002489048; state->dataHeatBalFanSys->PreviousMeasuredHumRat3(1) = 0.002480404; @@ -388,7 +327,7 @@ TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneAirTempTest) state->dataScheduleMgr->Schedule(state->dataHybridModel->HybridModelZone(1).ZoneMeasuredHumidityRatioSchedulePtr).CurrentValue = 0.002506251487737; - CorrectZoneHumRat(*state, 1); + thisZoneHB.correctHumRat(*state, 1); EXPECT_NEAR(4, state->dataHeatBal->Zone(1).NumOccHM, 0.1); // Case 6: Hybrid model infiltration with measured temperature (with HVAC) @@ -403,15 +342,15 @@ TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneAirTempTest) state->dataHybridModel->HybridModelZone(1).IncludeSystemSupplyParameters = true; state->dataHybridModel->HybridModelZone(1).HybridStartDayOfYear = 1; state->dataHybridModel->HybridModelZone(1).HybridEndDayOfYear = 2; - state->dataHeatBalFanSys->MAT(1) = 15.56; + thisZoneHB.MAT = 15.56; state->dataHeatBalFanSys->PreviousMeasuredZT1(1) = 15.56; state->dataHeatBalFanSys->PreviousMeasuredZT2(1) = 15.56; state->dataHeatBalFanSys->PreviousMeasuredZT3(1) = 15.56; state->dataHeatBal->Zone(1).ZoneVolCapMultpSens = 1.0; state->dataHeatBal->Zone(1).OutDryBulbTemp = -10.62; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.0077647; - state->dataHeatBalFanSys->MCPV(1) = 4456; // Assign TempDepCoef - state->dataHeatBalFanSys->MCPTV(1) = 60650; // Assign TempIndCoef + thisZoneHB.ZoneAirHumRat = 0.0077647; + thisZoneHB.MCPV = 4456; // Assign TempDepCoef + thisZoneHB.MCPTV = 60650; // Assign TempIndCoef state->dataEnvrn->OutBaroPress = 99500; state->dataEnvrn->OutHumRat = 0.00113669; state->dataHybridModel->HybridModelZone(1).ZoneMeasuredTemperatureSchedulePtr = 1; @@ -421,7 +360,7 @@ TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneAirTempTest) state->dataScheduleMgr->Schedule(state->dataHybridModel->HybridModelZone(1).ZoneSupplyAirTemperatureSchedulePtr).CurrentValue = 50; state->dataScheduleMgr->Schedule(state->dataHybridModel->HybridModelZone(1).ZoneSupplyAirMassFlowRateSchedulePtr).CurrentValue = 0.7974274; - CorrectZoneAirTemp(*state, ZoneTempChange, true); + ZoneTempChange = correctZoneAirTemps(*state, true); EXPECT_NEAR(0.49, state->dataHeatBal->Zone(1).InfilOAAirChangeRateHM, 0.01); // Case 7: Hybrid model infiltration with measured humidity ratio (with HVAC) @@ -439,8 +378,8 @@ TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneAirTempTest) state->dataHeatBal->Zone(1).Volume = 4000; state->dataHeatBal->Zone(1).OutDryBulbTemp = -10.62; state->dataHeatBal->Zone(1).ZoneVolCapMultpMoist = 1.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.001120003; - state->dataHeatBalFanSys->ZT(1) = -6.08; + thisZoneHB.ZoneAirHumRat = 0.001120003; + thisZoneHB.ZT = -6.08; state->dataEnvrn->OutHumRat = 0.0011366887816818931; state->dataHeatBalFanSys->PreviousMeasuredHumRat1(1) = 0.007855718; state->dataHeatBalFanSys->PreviousMeasuredHumRat2(1) = 0.007852847; @@ -453,7 +392,7 @@ TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneAirTempTest) state->dataScheduleMgr->Schedule(state->dataHybridModel->HybridModelZone(1).ZoneSupplyAirMassFlowRateSchedulePtr).CurrentValue = 0.8345; state->dataEnvrn->OutBaroPress = 99500; - CorrectZoneHumRat(*state, 1); + thisZoneHB.correctHumRat(*state, 1); EXPECT_NEAR(0.5, state->dataHeatBal->Zone(1).InfilOAAirChangeRateHM, 0.01); // Case 8: Hybrid model people count with measured temperature (with HVAC) @@ -468,16 +407,16 @@ TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneAirTempTest) state->dataHybridModel->HybridModelZone(1).IncludeSystemSupplyParameters = true; state->dataHybridModel->HybridModelZone(1).HybridStartDayOfYear = 1; state->dataHybridModel->HybridModelZone(1).HybridEndDayOfYear = 2; - state->dataHeatBalFanSys->MAT(1) = -2.89; + thisZoneHB.MAT = -2.89; state->dataHeatBalFanSys->PreviousMeasuredZT1(1) = 21.11; state->dataHeatBalFanSys->PreviousMeasuredZT2(1) = 21.11; state->dataHeatBalFanSys->PreviousMeasuredZT3(1) = 21.11; state->dataHeatBal->Zone(1).ZoneVolCapMultpSens = 1.0; state->dataHeatBal->Zone(1).OutDryBulbTemp = -6.71; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.0024964; + thisZoneHB.ZoneAirHumRat = 0.0024964; state->dataEnvrn->OutBaroPress = 98916.7; - state->dataHeatBalFanSys->MCPV(1) = 6616; // Assign TempDepCoef - state->dataHeatBalFanSys->MCPTV(1) = 138483.2; // Assign TempIndCoef + thisZoneHB.MCPV = 6616; // Assign TempDepCoef + thisZoneHB.MCPTV = 138483.2; // Assign TempIndCoef state->dataHybridModel->HybridModelZone(1).ZoneMeasuredTemperatureSchedulePtr = 1; state->dataHybridModel->HybridModelZone(1).ZoneSupplyAirTemperatureSchedulePtr = 2; state->dataHybridModel->HybridModelZone(1).ZoneSupplyAirMassFlowRateSchedulePtr = 3; @@ -491,7 +430,7 @@ TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneAirTempTest) state->dataScheduleMgr->Schedule(state->dataHybridModel->HybridModelZone(1).ZonePeopleSensibleFractionSchedulePtr).CurrentValue = 0.6; state->dataScheduleMgr->Schedule(state->dataHybridModel->HybridModelZone(1).ZonePeopleRadiationFractionSchedulePtr).CurrentValue = 0.3; - CorrectZoneAirTemp(*state, ZoneTempChange, true); + ZoneTempChange = correctZoneAirTemps(*state, true); EXPECT_NEAR(0, state->dataHeatBal->Zone(1).NumOccHM, 0.1); // Need to initialize SumIntGain // Case 9: Hybrid model people count with measured humidity ratio (with HVAC) @@ -508,8 +447,8 @@ TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneAirTempTest) state->dataHeatBal->Zone(1).Volume = 4000; state->dataHeatBal->Zone(1).OutDryBulbTemp = -10.62; state->dataHeatBal->Zone(1).ZoneVolCapMultpMoist = 1.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.001120003; - state->dataHeatBalFanSys->ZT(1) = -6.08; + thisZoneHB.ZoneAirHumRat = 0.001120003; + thisZoneHB.ZT = -6.08; state->dataEnvrn->OutHumRat = 0.0011366887816818931; state->dataHeatBalFanSys->PreviousMeasuredHumRat1(1) = 0.011085257; state->dataHeatBalFanSys->PreviousMeasuredHumRat2(1) = 0.011084959; @@ -528,87 +467,8 @@ TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneAirTempTest) state->dataScheduleMgr->Schedule(state->dataHybridModel->HybridModelZone(1).ZonePeopleRadiationFractionSchedulePtr).CurrentValue = 0.3; state->dataEnvrn->OutBaroPress = 99500; - CorrectZoneHumRat(*state, 1); + thisZoneHB.correctHumRat(*state, 1); EXPECT_NEAR(4, state->dataHeatBal->Zone(1).NumOccHM, 0.1); - - // Deallocate everything - state->dataHybridModel->clear_state(); - state->dataHeatBal->Zone.deallocate(); - state->dataRoomAirMod->AirModel.deallocate(); - state->dataHeatBalFanSys->ZTM1.deallocate(); - state->dataHeatBalFanSys->ZTM2.deallocate(); - state->dataHeatBalFanSys->ZTM3.deallocate(); - state->dataHeatBalFanSys->XMAT.deallocate(); - state->dataHeatBalFanSys->XM2T.deallocate(); - state->dataHeatBalFanSys->XM3T.deallocate(); - state->dataRoomAirMod->ZTOC.deallocate(); - state->dataRoomAirMod->ZTMX.deallocate(); - state->dataRoomAirMod->ZTM1MX.deallocate(); - state->dataHeatBalFanSys->WZoneTimeMinus1Temp.deallocate(); - state->dataHeatBalFanSys->WZoneTimeMinus2Temp.deallocate(); - state->dataHeatBalFanSys->WZoneTimeMinus3Temp.deallocate(); - state->dataHeatBalFanSys->WZoneTimeMinus1.deallocate(); - state->dataHeatBalFanSys->WZoneTimeMinus2.deallocate(); - state->dataHeatBalFanSys->WZoneTimeMinus3.deallocate(); - state->dataHeatBalFanSys->PreviousMeasuredHumRat1.deallocate(); - state->dataHeatBalFanSys->PreviousMeasuredHumRat2.deallocate(); - state->dataHeatBalFanSys->PreviousMeasuredHumRat3.deallocate(); - state->dataHeatBalFanSys->AIRRAT.deallocate(); - state->dataHeatBalFanSys->ZoneAirHumRat.deallocate(); - state->dataHeatBalFanSys->NonAirSystemResponse.deallocate(); - state->dataHeatBalFanSys->SysDepZoneLoadsLagged.deallocate(); - state->afn->exchangeData.deallocate(); - state->dataLoopNodes->Node.deallocate(); - state->dataHeatBalFanSys->TempTstatAir.deallocate(); - state->dataHeatBalFanSys->LoadCorrectionFactor.deallocate(); - state->dataHeatBalFanSys->MAT.deallocate(); - state->dataHeatBalFanSys->ZT.deallocate(); - state->dataHeatBalFanSys->PreviousMeasuredZT1.deallocate(); - state->dataHeatBalFanSys->PreviousMeasuredZT2.deallocate(); - state->dataHeatBalFanSys->PreviousMeasuredZT3.deallocate(); - state->dataHeatBalFanSys->MCPI.deallocate(); - state->dataHeatBalFanSys->MCPV.deallocate(); - state->dataHeatBalFanSys->MCPM.deallocate(); - state->dataHeatBalFanSys->MCPE.deallocate(); - state->dataHeatBalFanSys->MCPC.deallocate(); - state->dataHeatBalFanSys->MDotCPOA.deallocate(); - state->dataHeatBalFanSys->MDotOA.deallocate(); - state->dataHeatBalFanSys->MCPTI.deallocate(); - state->dataHeatBalFanSys->MCPTV.deallocate(); - state->dataHeatBalFanSys->MCPTM.deallocate(); - state->dataHeatBalFanSys->MCPTE.deallocate(); - state->dataHeatBalFanSys->MCPTC.deallocate(); - state->dataSurface->SurfaceWindow.deallocate(); - state->dataSurface->Surface.deallocate(); - state->dataHeatBalSurf->SurfHConvInt.deallocate(); - state->dataZoneTempPredictorCorrector->ZoneAirRelHum.deallocate(); - state->dataRoomAirMod->IsZoneDV.deallocate(); - state->dataRoomAirMod->IsZoneCV.deallocate(); - state->dataRoomAirMod->IsZoneUI.deallocate(); - state->dataRoomAirMod->ZoneDVMixedFlag.deallocate(); - state->dataHeatBal->ZnAirRpt.deallocate(); - state->dataZoneEquip->ZoneEquipConfig.deallocate(); - state->dataHeatBal->ZoneIntGain.deallocate(); - state->dataSize->ZoneEqSizing.deallocate(); - state->dataHeatBalFanSys->ZoneLatentGain.deallocate(); - state->dataHeatBalFanSys->SumLatentHTRadSys.deallocate(); - state->dataHeatBalFanSys->SumHmARaW.deallocate(); - state->dataHeatBalFanSys->SumConvHTRadSys.deallocate(); - state->dataHeatBalFanSys->SumConvPool.deallocate(); - state->dataHeatBalFanSys->SumHmARa.deallocate(); - state->dataHeatBalFanSys->MixingMassFlowXHumRat.deallocate(); - state->dataHeatBalFanSys->MixingMassFlowZone.deallocate(); - state->dataHeatBalFanSys->ZoneW1.deallocate(); - state->dataHeatBalFanSys->ZoneAirHumRatTemp.deallocate(); - state->dataHeatBalFanSys->SumLatentPool.deallocate(); - state->dataHeatBalFanSys->OAMFL.deallocate(); - state->dataHeatBalFanSys->VAMFL.deallocate(); - state->dataHeatBalFanSys->EAMFL.deallocate(); - state->dataHeatBalFanSys->EAMFLxHumRat.deallocate(); - state->dataHeatBalFanSys->CTMFL.deallocate(); - state->dataContaminantBalance->ZoneAirDensityCO.deallocate(); - state->dataContaminantBalance->ZoneGCGain.deallocate(); - state->dataScheduleMgr->Schedule.deallocate(); } TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneContaminantsTest) @@ -617,20 +477,13 @@ TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneContaminantsTest) // ZoneContaminantPredictorCorrector variable initialization state->dataHeatBal->Zone.allocate(1); state->dataHybridModel->HybridModelZone.allocate(1); + state->dataHybridModel->FlagHybridModel = true; state->dataRoomAirMod->AirModel.allocate(1); state->dataRoomAirMod->ZTOC.allocate(1); - state->dataHeatBalFanSys->AIRRAT.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); - state->dataHeatBalFanSys->NonAirSystemResponse.allocate(1); - state->dataHeatBalFanSys->NonAirSystemResponse(1) = 0.0; - state->dataHeatBalFanSys->SysDepZoneLoadsLagged.allocate(1); - state->dataHeatBalFanSys->SysDepZoneLoadsLagged(1) = 0.0; state->afn->exchangeData.allocate(1); state->dataLoopNodes->Node.allocate(1); state->dataHeatBalFanSys->TempTstatAir.allocate(1); state->dataHeatBalFanSys->LoadCorrectionFactor.allocate(1); - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->ZT.allocate(1); state->dataHeatBalFanSys->PreviousMeasuredZT1.allocate(1); state->dataHeatBalFanSys->PreviousMeasuredZT2.allocate(1); state->dataHeatBalFanSys->PreviousMeasuredZT3.allocate(1); @@ -643,32 +496,9 @@ TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneContaminantsTest) state->dataScheduleMgr->Schedule.allocate(7); // CalcZoneComponentLoadSums variable initialization - state->dataHeatBalFanSys->MCPI.allocate(1); - state->dataHeatBalFanSys->MCPI(1) = 0.0; - state->dataHeatBalFanSys->MCPV.allocate(1); - state->dataHeatBalFanSys->MCPM.allocate(1); - state->dataHeatBalFanSys->MCPM(1) = 0.0; - state->dataHeatBalFanSys->MCPE.allocate(1); - state->dataHeatBalFanSys->MCPE(1) = 0.0; - state->dataHeatBalFanSys->MCPC.allocate(1); - state->dataHeatBalFanSys->MCPC(1) = 0.0; - state->dataHeatBalFanSys->MDotCPOA.allocate(1); - state->dataHeatBalFanSys->MDotCPOA(1) = 0.0; - state->dataHeatBalFanSys->MDotOA.allocate(1); - state->dataHeatBalFanSys->MDotOA(1) = 0.0; - state->dataHeatBalFanSys->MCPTI.allocate(1); - state->dataHeatBalFanSys->MCPTI(1) = 0.0; - state->dataHeatBalFanSys->MCPTV.allocate(1); - state->dataHeatBalFanSys->MCPTM.allocate(1); - state->dataHeatBalFanSys->MCPTM(1) = 0.0; - state->dataHeatBalFanSys->MCPTE.allocate(1); - state->dataHeatBalFanSys->MCPTE(1) = 0.0; - state->dataHeatBalFanSys->MCPTC.allocate(1); - state->dataHeatBalFanSys->MCPTC(1) = 0.0; state->dataSurface->SurfaceWindow.allocate(1); state->dataSurface->Surface.allocate(2); state->dataHeatBalSurf->SurfHConvInt.allocate(1); - state->dataZoneTempPredictorCorrector->ZoneAirRelHum.allocate(1); state->dataRoomAirMod->IsZoneDV.dimension(1, false); state->dataRoomAirMod->IsZoneCV.dimension(1, false); state->dataRoomAirMod->IsZoneUI.dimension(1, false); @@ -678,22 +508,11 @@ TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneContaminantsTest) state->dataSize->ZoneEqSizing.allocate(1); // CorrectZoneContaminants variable initialization - state->dataHeatBalFanSys->MixingMassFlowZone.allocate(1); - state->dataHeatBalFanSys->MixingMassFlowZone(1) = 0.0; - state->dataHeatBalFanSys->ZoneW1.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRatTemp.allocate(1); - state->dataHeatBalFanSys->OAMFL.allocate(1); - state->dataHeatBalFanSys->OAMFL(1) = 0.0; - state->dataHeatBalFanSys->VAMFL.allocate(1); - state->dataHeatBalFanSys->VAMFL(1) = 0.0; - state->dataHeatBalFanSys->EAMFL.allocate(1); - state->dataHeatBalFanSys->EAMFL(1) = 0.0; - state->dataHeatBalFanSys->EAMFLxHumRat.allocate(1); - state->dataHeatBalFanSys->EAMFLxHumRat(1) = 0.0; - state->dataHeatBalFanSys->CTMFL.allocate(1); - state->dataHeatBalFanSys->CTMFL(1) = 0.0; - state->dataHeatBalFanSys->ZT.allocate(1); - state->dataHeatBalFanSys->ZT(1) = 0.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->spaceHeatBalance.allocate(1); + auto &thisZoneHB = state->dataZoneTempPredictorCorrector->zoneHeatBalance(1); + thisZoneHB.MixingMassFlowZone = 0.0; + thisZoneHB.ZT = 0.0; state->dataContaminantBalance->AZ.allocate(1); state->dataContaminantBalance->BZ.allocate(1); state->dataContaminantBalance->CZ.allocate(1); @@ -729,8 +548,11 @@ TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneContaminantsTest) state->dataHeatBal->Zone(1).IsControlled = true; state->dataHeatBal->Zone(1).Multiplier = 1; state->dataHeatBal->Zone(1).SystemZoneNodeNumber = 1; - state->dataHeatBal->Zone(1).HTSurfaceFirst = 0; - state->dataHeatBal->Zone(1).HTSurfaceLast = -1; + state->dataHeatBal->space.allocate(1); + state->dataHeatBal->spaceIntGainDevices.allocate(1); + state->dataHeatBal->Zone(1).spaceIndexes.emplace_back(1); + state->dataHeatBal->space(1).HTSurfaceFirst = 0; + state->dataHeatBal->space(1).HTSurfaceLast = -1; state->dataHeatBal->Zone(1).Volume = 4000; state->dataGlobal->TimeStepZone = 10.0 / 60.0; // Zone timestep in hours state->dataHVACGlobal->TimeStepSys = 10.0 / 60.0; @@ -754,7 +576,7 @@ TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneContaminantsTest) state->dataHybridModel->HybridModelZone(1).HybridStartDayOfYear = 1; state->dataHybridModel->HybridModelZone(1).HybridEndDayOfYear = 2; state->dataHeatBal->Zone(1).ZoneVolCapMultpCO2 = 1.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.001120003; + thisZoneHB.ZoneAirHumRat = 0.001120003; state->dataContaminantBalance->OutdoorCO2 = 387.6064554; state->dataEnvrn->OutHumRat = 0.001147; state->dataEnvrn->OutBaroPress = 99500; @@ -782,11 +604,11 @@ TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneContaminantsTest) state->dataHeatBal->Zone(1).Volume = 4000; state->dataHeatBal->Zone(1).ZoneVolCapMultpCO2 = 1.0; state->dataHeatBal->Zone(1).OutDryBulbTemp = -1.0394166434012677; - state->dataHeatBalFanSys->ZT(1) = -2.92; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.00112; + thisZoneHB.ZT = -2.92; + thisZoneHB.ZoneAirHumRat = 0.00112; state->dataContaminantBalance->OutdoorCO2 = 387.6064554; state->dataEnvrn->OutBaroPress = 98916.7; - state->dataHeatBalFanSys->OAMFL(1) = 0.700812; + thisZoneHB.OAMFL = 0.700812; state->dataContaminantBalance->ZoneCO2Gain(1) = 0.00001989; state->dataContaminantBalance->CO2ZoneTimeMinus1(1) = 387.9962885; state->dataContaminantBalance->CO2ZoneTimeMinus2(1) = 387.676037; @@ -809,8 +631,8 @@ TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneContaminantsTest) state->dataHybridModel->HybridModelZone(1).HybridStartDayOfYear = 1; state->dataHybridModel->HybridModelZone(1).HybridEndDayOfYear = 2; state->dataHeatBal->Zone(1).ZoneVolCapMultpCO2 = 1.0; - state->dataHeatBalFanSys->ZT(1) = 15.56; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.00809; + thisZoneHB.ZT = 15.56; + thisZoneHB.ZoneAirHumRat = 0.00809; state->dataHeatBal->Zone(1).OutDryBulbTemp = -10.7; state->dataEnvrn->OutBaroPress = 99500; state->dataContaminantBalance->ZoneCO2Gain(1) = 0.0; @@ -841,8 +663,8 @@ TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneContaminantsTest) state->dataHybridModel->HybridModelZone(1).HybridStartDayOfYear = 1; state->dataHybridModel->HybridModelZone(1).HybridEndDayOfYear = 2; state->dataHeatBal->Zone(1).ZoneVolCapMultpCO2 = 1.0; - state->dataHeatBalFanSys->ZT(1) = 21.1; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.01102; + thisZoneHB.ZT = 21.1; + thisZoneHB.ZoneAirHumRat = 0.01102; state->dataEnvrn->OutBaroPress = 98933.3; state->dataContaminantBalance->ZoneCO2Gain(1) = 0.00003333814; state->dataContaminantBalance->ZoneCO2GainExceptPeople(1) = 0.0; @@ -866,68 +688,4 @@ TEST_F(EnergyPlusFixture, HybridModel_CorrectZoneContaminantsTest) CorrectZoneContaminants(*state, true); EXPECT_NEAR(7.27, state->dataHeatBal->Zone(1).NumOccHM, 0.1); - - // Deallocate everything - state->dataHeatBal->Zone.deallocate(); - state->dataHybridModel->HybridModelZone.deallocate(); - state->dataRoomAirMod->AirModel.deallocate(); - state->dataRoomAirMod->ZTOC.deallocate(); - state->dataContaminantBalance->CO2ZoneTimeMinus1Temp.deallocate(); - state->dataContaminantBalance->CO2ZoneTimeMinus2Temp.deallocate(); - state->dataContaminantBalance->CO2ZoneTimeMinus3Temp.deallocate(); - state->dataContaminantBalance->CO2ZoneTimeMinus1.deallocate(); - state->dataContaminantBalance->CO2ZoneTimeMinus2.deallocate(); - state->dataContaminantBalance->CO2ZoneTimeMinus3.deallocate(); - state->dataHeatBalFanSys->AIRRAT.deallocate(); - state->dataHeatBalFanSys->ZoneAirHumRat.deallocate(); - state->dataHeatBalFanSys->NonAirSystemResponse.deallocate(); - state->dataHeatBalFanSys->SysDepZoneLoadsLagged.deallocate(); - state->afn->exchangeData.deallocate(); - state->dataLoopNodes->Node.deallocate(); - state->dataHeatBalFanSys->TempTstatAir.deallocate(); - state->dataHeatBalFanSys->LoadCorrectionFactor.deallocate(); - state->dataHeatBalFanSys->MAT.deallocate(); - state->dataHeatBalFanSys->ZT.deallocate(); - state->dataHeatBalFanSys->PreviousMeasuredZT1.deallocate(); - state->dataHeatBalFanSys->PreviousMeasuredZT2.deallocate(); - state->dataHeatBalFanSys->PreviousMeasuredZT3.deallocate(); - state->dataHeatBalFanSys->MCPI.deallocate(); - state->dataHeatBalFanSys->MCPV.deallocate(); - state->dataHeatBalFanSys->MCPM.deallocate(); - state->dataHeatBalFanSys->MCPE.deallocate(); - state->dataHeatBalFanSys->MCPC.deallocate(); - state->dataHeatBalFanSys->MDotCPOA.deallocate(); - state->dataHeatBalFanSys->MDotOA.deallocate(); - state->dataHeatBalFanSys->MCPTI.deallocate(); - state->dataHeatBalFanSys->MCPTV.deallocate(); - state->dataHeatBalFanSys->MCPTM.deallocate(); - state->dataHeatBalFanSys->MCPTE.deallocate(); - state->dataHeatBalFanSys->MCPTC.deallocate(); - state->dataSurface->SurfaceWindow.deallocate(); - state->dataSurface->Surface.deallocate(); - state->dataHeatBalSurf->SurfHConvInt.deallocate(); - state->dataZoneTempPredictorCorrector->ZoneAirRelHum.deallocate(); - state->dataRoomAirMod->IsZoneDV.deallocate(); - state->dataRoomAirMod->IsZoneCV.deallocate(); - state->dataRoomAirMod->IsZoneUI.deallocate(); - state->dataRoomAirMod->ZoneDVMixedFlag.deallocate(); - state->dataHeatBal->ZnAirRpt.deallocate(); - state->dataZoneEquip->ZoneEquipConfig.deallocate(); - state->dataSize->ZoneEqSizing.deallocate(); - state->dataHeatBalFanSys->MixingMassFlowZone.deallocate(); - state->dataHeatBalFanSys->ZoneW1.deallocate(); - state->dataHeatBalFanSys->ZoneAirHumRatTemp.deallocate(); - state->dataHeatBalFanSys->OAMFL.deallocate(); - state->dataHeatBalFanSys->VAMFL.deallocate(); - state->dataHeatBalFanSys->EAMFL.deallocate(); - state->dataHeatBalFanSys->EAMFLxHumRat.deallocate(); - state->dataHeatBalFanSys->CTMFL.deallocate(); - state->dataContaminantBalance->ZoneAirCO2.deallocate(); - state->dataContaminantBalance->ZoneAirCO2Temp.deallocate(); - state->dataContaminantBalance->ZoneAirDensityCO.deallocate(); - state->dataContaminantBalance->ZoneCO2Gain.deallocate(); - state->dataContaminantBalance->ZoneCO2GainExceptPeople.deallocate(); - state->dataContaminantBalance->ZoneGCGain.deallocate(); - state->dataContaminantBalance->MixingMassFlowCO2.deallocate(); - state->dataScheduleMgr->Schedule.deallocate(); } diff --git a/tst/EnergyPlus/unit/InternalHeatGains.unit.cc b/tst/EnergyPlus/unit/InternalHeatGains.unit.cc index 4e3d087f84d..2313b840041 100644 --- a/tst/EnergyPlus/unit/InternalHeatGains.unit.cc +++ b/tst/EnergyPlus/unit/InternalHeatGains.unit.cc @@ -57,7 +57,6 @@ #include #include #include -#include #include #include #include @@ -72,6 +71,7 @@ #include #include #include +#include using namespace EnergyPlus; @@ -474,11 +474,10 @@ TEST_F(EnergyPlusFixture, InternalHeatGains_ElectricEquipITE_BeginEnvironmentRes HeatBalanceManager::GetZoneData(*state, ErrorsFound); ASSERT_FALSE(ErrorsFound); - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); - state->dataHeatBalFanSys->MAT(1) = 24.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.008; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 24.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.008; InternalHeatGains::GetInternalHeatGainsInput(*state); InternalHeatGains::CalcZoneITEq(*state); @@ -678,7 +677,7 @@ TEST_F(EnergyPlusFixture, InternalHeatGains_CheckZoneComponentLoadSubtotals) InternalHeatGains::UpdateInternalGainValues(*state); // Check total of all convective gains - totConvGains = InternalHeatGains::SumAllInternalConvectionGains(*state, zoneNum); + totConvGains = InternalHeatGains::zoneSumAllInternalConvectionGains(*state, zoneNum); EXPECT_EQ(totConvGains, expectedTotConvGains); // Check subtotals used in zone component loads @@ -889,13 +888,12 @@ TEST_F(EnergyPlusFixture, InternalHeatGains_ElectricEquipITE_ApproachTemperature HeatBalanceManager::GetZoneData(*state, ErrorsFound); ASSERT_FALSE(ErrorsFound); - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); state->dataHeatBal->ZoneRpt.allocate(1); state->dataZoneEquip->ZoneEquipConfig.allocate(1); - state->dataHeatBalFanSys->MAT(1) = 24.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.008; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 24.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.008; InternalHeatGains::GetInternalHeatGainsInput(*state); @@ -1044,11 +1042,10 @@ TEST_F(EnergyPlusFixture, InternalHeatGains_ElectricEquipITE_DefaultCurves) HeatBalanceManager::GetZoneData(*state, ErrorsFound); ASSERT_FALSE(ErrorsFound); - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); - state->dataHeatBalFanSys->MAT(1) = 24.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.008; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 24.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.008; InternalHeatGains::GetInternalHeatGainsInput(*state); InternalHeatGains::CalcZoneITEq(*state); @@ -1565,11 +1562,10 @@ TEST_F(EnergyPlusFixture, InternalHeatGains_AdjustedSupplyGoodInletNode) HeatBalanceManager::GetZoneData(*state, ErrorsFound); ASSERT_FALSE(ErrorsFound); - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); - state->dataHeatBalFanSys->MAT(1) = 24.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.008; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 24.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.008; InternalHeatGains::GetInternalHeatGainsInput(*state); ASSERT_FALSE(ErrorsFound); @@ -1788,11 +1784,10 @@ TEST_F(EnergyPlusFixture, InternalHeatGains_AdjustedSupplyBadInletNode) HeatBalanceManager::GetZoneData(*state, ErrorsFound); ASSERT_FALSE(ErrorsFound); - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); - state->dataHeatBalFanSys->MAT(1) = 24.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.008; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 24.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.008; EXPECT_ANY_THROW(InternalHeatGains::GetInternalHeatGainsInput(*state)); } @@ -2014,11 +2009,10 @@ TEST_F(EnergyPlusFixture, InternalHeatGains_FlowControlWithApproachTemperaturesG HeatBalanceManager::GetZoneData(*state, ErrorsFound); ASSERT_FALSE(ErrorsFound); - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); - state->dataHeatBalFanSys->MAT(1) = 24.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.008; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 24.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.008; InternalHeatGains::GetInternalHeatGainsInput(*state); ASSERT_FALSE(ErrorsFound); @@ -2241,11 +2235,10 @@ TEST_F(EnergyPlusFixture, InternalHeatGains_FlowControlWithApproachTemperaturesB HeatBalanceManager::GetZoneData(*state, ErrorsFound); ASSERT_FALSE(ErrorsFound); - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); - state->dataHeatBalFanSys->MAT(1) = 24.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.008; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 24.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.008; ASSERT_ANY_THROW(InternalHeatGains::GetInternalHeatGainsInput(*state)); } @@ -2467,11 +2460,10 @@ TEST_F(EnergyPlusFixture, InternalHeatGains_WarnMissingInletNode) HeatBalanceManager::GetZoneData(*state, ErrorsFound); ASSERT_FALSE(ErrorsFound); - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); - state->dataHeatBalFanSys->MAT(1) = 24.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.008; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 24.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.008; InternalHeatGains::GetInternalHeatGainsInput(*state); ASSERT_FALSE(ErrorsFound); @@ -2646,11 +2638,10 @@ TEST_F(EnergyPlusFixture, ITEwithUncontrolledZoneTest) HeatBalanceManager::GetZoneData(*state, ErrorsFound); ASSERT_FALSE(ErrorsFound); - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); - state->dataHeatBalFanSys->MAT(1) = 24.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.008; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 24.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.008; InternalHeatGains::GetInternalHeatGainsInput(*state); ASSERT_FALSE(ErrorsFound); @@ -2787,12 +2778,11 @@ TEST_F(EnergyPlusFixture, ITE_Env_Class_Fix_41C) HeatBalanceManager::GetZoneData(*state, ErrorsFound); ASSERT_FALSE(ErrorsFound); - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); // Test 1: 41C; - state->dataHeatBalFanSys->MAT(1) = 41.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.015; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 41.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.015; InternalHeatGains::GetInternalHeatGainsInput(*state); ASSERT_FALSE(ErrorsFound); @@ -2805,7 +2795,7 @@ TEST_F(EnergyPlusFixture, ITE_Env_Class_Fix_41C) int NZ = 1; int spaceNum = 1; int EnvClass = 3; - Real64 TAirIn = state->dataHeatBalFanSys->MAT(1); + Real64 TAirIn = state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT; Real64 TDPAirIn = 20; Real64 RHAirIn = 40; @@ -2989,12 +2979,11 @@ TEST_F(EnergyPlusFixture, ITE_Env_Class_Fix_39C) HeatBalanceManager::GetZoneData(*state, ErrorsFound); ASSERT_FALSE(ErrorsFound); - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); // Test 2: 39C; - state->dataHeatBalFanSys->MAT(1) = 39.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.015; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 39.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.015; InternalHeatGains::GetInternalHeatGainsInput(*state); ASSERT_FALSE(ErrorsFound); @@ -3007,7 +2996,7 @@ TEST_F(EnergyPlusFixture, ITE_Env_Class_Fix_39C) int NZ = 1; int spaceNum = 1; int EnvClass = 3; - Real64 TAirIn = state->dataHeatBalFanSys->MAT(1); + Real64 TAirIn = state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT; Real64 TDPAirIn = 20; Real64 RHAirIn = 40; @@ -3198,14 +3187,13 @@ TEST_F(EnergyPlusFixture, ITE_Env_Class_Update_Class_H1) HeatBalanceManager::GetZoneData(*state, ErrorsFound); ASSERT_FALSE(ErrorsFound); - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); state->dataEnvrn->StdBaroPress = 101325.0; // Test: 41C - state->dataHeatBalFanSys->MAT(1) = 41.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.015; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 41.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.015; InternalHeatGains::GetInternalHeatGainsInput(*state); ASSERT_FALSE(ErrorsFound); @@ -3220,7 +3208,7 @@ TEST_F(EnergyPlusFixture, ITE_Env_Class_Update_Class_H1) int NZ = 1; int spaceNum = 1; int EnvClass = static_cast(thisZoneITEq.Class); // DataHeatBalance::ITEClass::H1, or 7 - Real64 TAirIn = state->dataHeatBalFanSys->MAT(1); + Real64 TAirIn = state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT; Real64 TDPAirIn = 20; Real64 RHAirIn = 40; @@ -3296,8 +3284,8 @@ TEST_F(EnergyPlusFixture, ITE_Env_Class_Update_Class_H1) EXPECT_EQ(thisspaceRpt.ITEqTimeOutOfOperRange, state->dataGlobal->TimeStepZone); // Now Test 33C (after PR9541/Issue9538 is merged/fixed) - state->dataHeatBalFanSys->MAT(1) = 33.0; - // state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.015; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 33.0; + // state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.015; InternalHeatGains::GetInternalHeatGainsInput(*state); ASSERT_FALSE(ErrorsFound); @@ -3306,7 +3294,7 @@ TEST_F(EnergyPlusFixture, ITE_Env_Class_Update_Class_H1) InternalHeatGains::CalcZoneITEq(*state); - TAirIn = state->dataHeatBalFanSys->MAT(1); + TAirIn = state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT; TDPAirIn = 20.323364421767739; RHAirIn = 47.395745113895885; diff --git a/tst/EnergyPlus/unit/LowTempRadiantSystem.unit.cc b/tst/EnergyPlus/unit/LowTempRadiantSystem.unit.cc index d79feed7fd0..e4d9765aa59 100644 --- a/tst/EnergyPlus/unit/LowTempRadiantSystem.unit.cc +++ b/tst/EnergyPlus/unit/LowTempRadiantSystem.unit.cc @@ -55,7 +55,6 @@ #include #include #include -#include #include #include #include @@ -74,6 +73,7 @@ #include #include #include +#include using namespace EnergyPlus; using namespace EnergyPlus::LowTempRadiantSystem; @@ -2396,11 +2396,11 @@ TEST_F(LowTempRadiantSystemTest, CalcLowTempCFloRadiantSystem_OperationMode) state->dataLowTempRadSys->NumOfCFloLowTempRadSysDes = 1; state->dataLowTempRadSys->CflowRadiantSysDesign.allocate(state->dataLowTempRadSys->NumOfCFloLowTempRadSysDes); state->dataScheduleMgr->Schedule.allocate(3); - state->dataHeatBalFanSys->MAT.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); state->dataScheduleMgr->Schedule(1).CurrentValue = 1; state->dataScheduleMgr->Schedule(2).CurrentValue = 22.0; state->dataScheduleMgr->Schedule(3).CurrentValue = 25.0; - state->dataHeatBalFanSys->MAT(1) = 21.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 21.0; state->dataLowTempRadSys->CFloRadSys(RadSysNum).NumOfSurfaces = 0; state->dataLowTempRadSys->TotalNumOfRadSystems = 0; state->dataLowTempRadSys->CFloRadSys(RadSysNum).ZonePtr = 1; @@ -2436,13 +2436,9 @@ TEST_F(LowTempRadiantSystemTest, CalcLowTempCFloRadiantSystem_OperationMode) // Cooling state->dataLowTempRadSys->CFloRadSys(RadSysNum).CoolingSystem = false; state->dataLowTempRadSys->CFloRadSys(RadSysNum).HeatingSystem = true; - state->dataHeatBalFanSys->MAT(1) = 26.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 26.0; state->dataLowTempRadSys->CFloRadSys(RadSysNum).calculateLowTemperatureRadiantSystem(*state, Load); EXPECT_EQ(NotOperating, state->dataLowTempRadSys->CFloRadSys(RadSysNum).OperatingMode); - - state->dataLowTempRadSys->CFloRadSys.deallocate(); - state->dataScheduleMgr->Schedule.deallocate(); - state->dataHeatBalFanSys->MAT.deallocate(); } TEST_F(LowTempRadiantSystemTest, CalcLowTempHydrRadiantSystem_OperationMode) @@ -2462,11 +2458,11 @@ TEST_F(LowTempRadiantSystemTest, CalcLowTempHydrRadiantSystem_OperationMode) state->dataLowTempRadSys->HydrRadSys(RadSysNum).SurfacePtr.allocate(1); state->dataLowTempRadSys->HydrRadSys(RadSysNum).SurfacePtr(1) = 1; state->dataScheduleMgr->Schedule.allocate(3); - state->dataHeatBalFanSys->MAT.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); state->dataScheduleMgr->Schedule(1).CurrentValue = 1; state->dataScheduleMgr->Schedule(2).CurrentValue = 22.0; state->dataScheduleMgr->Schedule(3).CurrentValue = 25.0; - state->dataHeatBalFanSys->MAT(1) = 21.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 21.0; state->dataLowTempRadSys->HydrRadSys(RadSysNum).NumOfSurfaces = 0; state->dataLowTempRadSys->TotalNumOfRadSystems = 0; state->dataLowTempRadSys->HydrRadSys(RadSysNum).ZonePtr = 1; @@ -2496,13 +2492,9 @@ TEST_F(LowTempRadiantSystemTest, CalcLowTempHydrRadiantSystem_OperationMode) // Cooling state->dataLowTempRadSys->HydrRadSys(RadSysNum).CoolingSystem = false; state->dataLowTempRadSys->HydrRadSys(RadSysNum).HeatingSystem = true; - state->dataHeatBalFanSys->MAT(1) = 26.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 26.0; state->dataLowTempRadSys->HydrRadSys(RadSysNum).calculateLowTemperatureRadiantSystem(*state, Load); EXPECT_EQ(NotOperating, state->dataLowTempRadSys->HydrRadSys(RadSysNum).OperatingMode); - - state->dataLowTempRadSys->HydrRadSys.deallocate(); - state->dataScheduleMgr->Schedule.deallocate(); - state->dataHeatBalFanSys->MAT.deallocate(); } TEST_F(LowTempRadiantSystemTest, SizeRadSysTubeLengthTest) @@ -2934,7 +2926,7 @@ TEST_F(LowTempRadiantSystemTest, setRadiantSystemControlTemperatureTest) Real64 actualResult; Real64 acceptibleError = 0.001; - state->dataHeatBalFanSys->MAT.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); state->dataHeatBal->ZoneMRT.allocate(1); state->dataHeatBal->Zone.allocate(1); state->dataHeatBalSurf->SurfTempIn.allocate(1); @@ -2944,7 +2936,7 @@ TEST_F(LowTempRadiantSystemTest, setRadiantSystemControlTemperatureTest) state->dataLowTempRadSys->ElecRadSys.allocate(1); // Test Data - state->dataHeatBalFanSys->MAT(1) = 23.456; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 23.456; state->dataHeatBal->ZoneMRT(1) = 12.345; state->dataHeatBal->Zone(1).OutDryBulbTemp = 34.567; state->dataHeatBal->Zone(1).OutWetBulbTemp = 1.234; @@ -2962,19 +2954,19 @@ TEST_F(LowTempRadiantSystemTest, setRadiantSystemControlTemperatureTest) // Test 1: MAT Control state->dataLowTempRadSys->HydrRadSys(1).controlType = LowTempRadiantControlTypes::MATControl; - expectedResult = state->dataHeatBalFanSys->MAT(1); + expectedResult = state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT; actualResult = 0.0; // reset actualResult = state->dataLowTempRadSys->HydrRadSys(1).setRadiantSystemControlTemperature(*state, state->dataLowTempRadSys->HydrRadSys(1).controlType); EXPECT_NEAR(expectedResult, actualResult, acceptibleError); state->dataLowTempRadSys->CFloRadSys(1).controlType = LowTempRadiantControlTypes::MATControl; - expectedResult = state->dataHeatBalFanSys->MAT(1); + expectedResult = state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT; actualResult = 0.0; // reset actualResult = state->dataLowTempRadSys->CFloRadSys(1).setRadiantSystemControlTemperature(*state, state->dataLowTempRadSys->CFloRadSys(1).controlType); EXPECT_NEAR(expectedResult, actualResult, acceptibleError); state->dataLowTempRadSys->ElecRadSys(1).controlType = LowTempRadiantControlTypes::MATControl; - expectedResult = state->dataHeatBalFanSys->MAT(1); + expectedResult = state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT; actualResult = 0.0; // reset actualResult = state->dataLowTempRadSys->ElecRadSys(1).setRadiantSystemControlTemperature(*state, state->dataLowTempRadSys->ElecRadSys(1).controlType); @@ -3002,19 +2994,19 @@ TEST_F(LowTempRadiantSystemTest, setRadiantSystemControlTemperatureTest) // Test 3: Operative Temperature Control state->dataLowTempRadSys->HydrRadSys(1).controlType = LowTempRadiantControlTypes::OperativeControl; - expectedResult = (state->dataHeatBalFanSys->MAT(1) + state->dataHeatBal->ZoneMRT(1)) / 2.0; + expectedResult = (state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT + state->dataHeatBal->ZoneMRT(1)) / 2.0; actualResult = 0.0; // reset actualResult = state->dataLowTempRadSys->HydrRadSys(1).setRadiantSystemControlTemperature(*state, state->dataLowTempRadSys->HydrRadSys(1).controlType); EXPECT_NEAR(expectedResult, actualResult, acceptibleError); state->dataLowTempRadSys->CFloRadSys(1).controlType = LowTempRadiantControlTypes::OperativeControl; - expectedResult = (state->dataHeatBalFanSys->MAT(1) + state->dataHeatBal->ZoneMRT(1)) / 2.0; + expectedResult = (state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT + state->dataHeatBal->ZoneMRT(1)) / 2.0; actualResult = 0.0; // reset actualResult = state->dataLowTempRadSys->CFloRadSys(1).setRadiantSystemControlTemperature(*state, state->dataLowTempRadSys->CFloRadSys(1).controlType); EXPECT_NEAR(expectedResult, actualResult, acceptibleError); state->dataLowTempRadSys->ElecRadSys(1).controlType = LowTempRadiantControlTypes::OperativeControl; - expectedResult = (state->dataHeatBalFanSys->MAT(1) + state->dataHeatBal->ZoneMRT(1)) / 2.0; + expectedResult = (state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT + state->dataHeatBal->ZoneMRT(1)) / 2.0; actualResult = 0.0; // reset actualResult = state->dataLowTempRadSys->ElecRadSys(1).setRadiantSystemControlTemperature(*state, state->dataLowTempRadSys->ElecRadSys(1).controlType); diff --git a/tst/EnergyPlus/unit/MoistureBalanceEMPD.unit.cc b/tst/EnergyPlus/unit/MoistureBalanceEMPD.unit.cc index 490a01cc2a1..d8f3d531b60 100644 --- a/tst/EnergyPlus/unit/MoistureBalanceEMPD.unit.cc +++ b/tst/EnergyPlus/unit/MoistureBalanceEMPD.unit.cc @@ -56,7 +56,6 @@ #include #include #include -#include #include #include #include @@ -66,6 +65,7 @@ #include #include #include +#include using namespace EnergyPlus; @@ -110,12 +110,11 @@ TEST_F(EnergyPlusFixture, CheckEMPDCalc) // Zone surface.Zone = 1; - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); state->dataMstBal->RhoVaporAirIn.allocate(1); state->dataMstBal->HMassConvInFD.allocate(1); - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->MAT(1) = 20.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.0061285406810457849; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 20.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.0061285406810457849; // Construction surface.Construction = 1; @@ -151,10 +150,6 @@ TEST_F(EnergyPlusFixture, CheckEMPDCalc) EXPECT_DOUBLE_EQ(0.0070186500259181136, state->dataMstBalEMPD->RVSurfLayer(1)); EXPECT_DOUBLE_EQ(0.0051469229632164605, state->dataMstBalEMPD->RVDeepLayer(1)); EXPECT_DOUBLE_EQ(-0.47694608375620229, state->dataMstBalEMPD->HeatFluxLatent(1)); - - // Clean up - state->dataHeatBalFanSys->ZoneAirHumRat.deallocate(); - state->dataMstBal->RhoVaporAirIn.deallocate(); } TEST_F(EnergyPlusFixture, EMPDAutocalcDepth) @@ -235,12 +230,11 @@ TEST_F(EnergyPlusFixture, EMPDRcoating) // Zone surface.Zone = 1; - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); state->dataMstBal->RhoVaporAirIn.allocate(1); state->dataMstBal->HMassConvInFD.allocate(1); - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->MAT(1) = 20.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.0061285406810457849; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 20.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.0061285406810457849; // Construction surface.Construction = 1; @@ -276,10 +270,6 @@ TEST_F(EnergyPlusFixture, EMPDRcoating) EXPECT_DOUBLE_EQ(0.0070183147759991828, state->dataMstBalEMPD->RVSurfLayer(1)); EXPECT_DOUBLE_EQ(0.0051469229632164605, state->dataMstBalEMPD->RVDeepLayer(1)); EXPECT_DOUBLE_EQ(-0.45295492522779346, state->dataMstBalEMPD->HeatFluxLatent(1)); - - // Clean up - state->dataHeatBalFanSys->ZoneAirHumRat.deallocate(); - state->dataMstBal->RhoVaporAirIn.deallocate(); } TEST_F(EnergyPlusFixture, CheckEMPDCalc_Slope) { @@ -325,12 +315,11 @@ TEST_F(EnergyPlusFixture, CheckEMPDCalc_Slope) // Zone int zoneNum = 1; surface.Zone = 1; - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(zoneNum); state->dataMstBal->RhoVaporAirIn.allocate(surfNum); state->dataMstBal->HMassConvInFD.allocate(surfNum); - state->dataHeatBalFanSys->MAT.allocate(zoneNum); - state->dataHeatBalFanSys->MAT(zoneNum) = 20.0; - state->dataHeatBalFanSys->ZoneAirHumRat(zoneNum) = 0.0061285406810457849; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(zoneNum); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum).MAT = 20.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(zoneNum).ZoneAirHumRat = 0.0061285406810457849; // Construction int constNum = 1; diff --git a/tst/EnergyPlus/unit/OutputReportTabular.unit.cc b/tst/EnergyPlus/unit/OutputReportTabular.unit.cc index ac342ebb653..a37b023e296 100644 --- a/tst/EnergyPlus/unit/OutputReportTabular.unit.cc +++ b/tst/EnergyPlus/unit/OutputReportTabular.unit.cc @@ -6949,8 +6949,9 @@ TEST_F(EnergyPlusFixture, OutputReportTabularTest_GetDelaySequencesTwice_test) state->dataHeatBal->space.allocate(state->dataGlobal->numSpaces); state->dataViewFactor->NumOfRadiantEnclosures = 4; - state->dataHeatBal->Zone(iZone).HTSurfaceFirst = 1; - state->dataHeatBal->Zone(iZone).HTSurfaceLast = 1; + state->dataHeatBal->Zone(iZone).spaceIndexes.emplace_back(iZone); + state->dataHeatBal->space(iZone).HTSurfaceFirst = 1; + state->dataHeatBal->space(iZone).HTSurfaceLast = 1; state->dataHeatBal->space(iZone).radiantEnclosureNum = 1; state->dataSurface->TotSurfaces = 4; @@ -7111,8 +7112,10 @@ TEST_F(SQLiteFixture, OutputReportTabular_WriteLoadComponentSummaryTables_AirLoo state->dataHeatBal->Zone(1).ListMultiplier = 1; state->dataHeatBal->Zone(1).FloorArea = 100.; // Trick E+ into not iterating on Surfaces - state->dataHeatBal->Zone(1).HTSurfaceFirst = 1; - state->dataHeatBal->Zone(1).HTSurfaceLast = 0; + state->dataHeatBal->Zone(1).spaceIndexes.emplace_back(1); + state->dataHeatBal->space.allocate(1); + state->dataHeatBal->space(1).HTSurfaceFirst = 1; + state->dataHeatBal->space(1).HTSurfaceLast = 0; // Cool Peak on 1st DD at 16:00 and Heat Peak on 2nd DD at 1:00 state->dataSize->CalcFinalZoneSizing.allocate(state->dataGlobal->NumOfZones); @@ -8322,8 +8325,9 @@ TEST_F(EnergyPlusFixture, OutputReportTabularTest_GetDelaySequencesSurfaceOrder_ state->dataHeatBal->space.allocate(state->dataGlobal->numSpaces); state->dataViewFactor->NumOfRadiantEnclosures = 1; - state->dataHeatBal->Zone(iZone).HTSurfaceFirst = 1; - state->dataHeatBal->Zone(iZone).HTSurfaceLast = 4; + state->dataHeatBal->Zone(iZone).spaceIndexes.emplace_back(iZone); + state->dataHeatBal->space(iZone).HTSurfaceFirst = 1; + state->dataHeatBal->space(iZone).HTSurfaceLast = 4; state->dataHeatBal->space(iZone).radiantEnclosureNum = 1; int radEnclosureNum = 1; diff --git a/tst/EnergyPlus/unit/PackagedTerminalHeatPump.unit.cc b/tst/EnergyPlus/unit/PackagedTerminalHeatPump.unit.cc index e4782176ea6..138384be274 100644 --- a/tst/EnergyPlus/unit/PackagedTerminalHeatPump.unit.cc +++ b/tst/EnergyPlus/unit/PackagedTerminalHeatPump.unit.cc @@ -3862,12 +3862,11 @@ TEST_F(EnergyPlusFixture, PTACDrawAirfromReturnNodeAndPlenum_Test) SizingManager::GetOARequirements(*state); InternalHeatGains::GetInternalHeatGainsInput(*state); - state->dataHeatBalFanSys->MAT.allocate(6); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(6); - state->dataHeatBalFanSys->MAT = 23.0; - state->dataHeatBalFanSys->ZoneAirHumRat = 0.001; - state->dataHeatBalFanSys->NonAirSystemResponse.allocate(6); - state->dataHeatBalFanSys->SysDepZoneLoads.allocate(6); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(6); + for (auto &thisZoneHB : state->dataZoneTempPredictorCorrector->zoneHeatBalance) { + thisZoneHB.MAT = 23.0; + thisZoneHB.ZoneAirHumRat = 0.001; + } state->dataZoneEnergyDemand->ZoneSysEnergyDemand.allocate(state->dataGlobal->NumOfZones); state->dataZoneEnergyDemand->ZoneSysMoistureDemand.allocate(state->dataGlobal->NumOfZones); @@ -3882,8 +3881,10 @@ TEST_F(EnergyPlusFixture, PTACDrawAirfromReturnNodeAndPlenum_Test) state->dataUnitarySystems->getInputOnceFlag = false; for (int i = 1; i <= state->dataGlobal->NumOfZones; ++i) { if (!state->dataZoneEquip->ZoneEquipConfig(i).IsControlled) continue; - state->dataLoopNodes->Node(state->dataZoneEquip->ZoneEquipConfig(i).ZoneNode).Temp = state->dataHeatBalFanSys->MAT(i); - state->dataLoopNodes->Node(state->dataZoneEquip->ZoneEquipConfig(i).ZoneNode).HumRat = state->dataHeatBalFanSys->ZoneAirHumRat(i); + state->dataLoopNodes->Node(state->dataZoneEquip->ZoneEquipConfig(i).ZoneNode).Temp = + state->dataZoneTempPredictorCorrector->zoneHeatBalance(i).MAT; + state->dataLoopNodes->Node(state->dataZoneEquip->ZoneEquipConfig(i).ZoneNode).HumRat = + state->dataZoneTempPredictorCorrector->zoneHeatBalance(i).ZoneAirHumRat; state->dataLoopNodes->Node(state->dataZoneEquip->ZoneEquipConfig(i).ZoneNode).Enthalpy = Psychrometrics::PsyHFnTdbW(state->dataLoopNodes->Node(state->dataZoneEquip->ZoneEquipConfig(i).ZoneNode).Temp, state->dataLoopNodes->Node(state->dataZoneEquip->ZoneEquipConfig(i).ZoneNode).HumRat); @@ -3948,8 +3949,10 @@ TEST_F(EnergyPlusFixture, PTACDrawAirfromReturnNodeAndPlenum_Test) state->dataLoopNodes->Node(mixerMixedNode).MassFlowRateMaxAvail = 0.26908 * 1.2; for (int i = 1; i <= state->dataGlobal->NumOfZones; ++i) { if (!state->dataZoneEquip->ZoneEquipConfig(i).IsControlled) continue; - state->dataLoopNodes->Node(state->dataZoneEquip->ZoneEquipConfig(i).ZoneNode).Temp = state->dataHeatBalFanSys->MAT(i); - state->dataLoopNodes->Node(state->dataZoneEquip->ZoneEquipConfig(i).ZoneNode).HumRat = state->dataHeatBalFanSys->ZoneAirHumRat(i); + state->dataLoopNodes->Node(state->dataZoneEquip->ZoneEquipConfig(i).ZoneNode).Temp = + state->dataZoneTempPredictorCorrector->zoneHeatBalance(i).MAT; + state->dataLoopNodes->Node(state->dataZoneEquip->ZoneEquipConfig(i).ZoneNode).HumRat = + state->dataZoneTempPredictorCorrector->zoneHeatBalance(i).ZoneAirHumRat; state->dataLoopNodes->Node(state->dataZoneEquip->ZoneEquipConfig(i).ZoneNode).Enthalpy = Psychrometrics::PsyHFnTdbW(state->dataLoopNodes->Node(state->dataZoneEquip->ZoneEquipConfig(i).ZoneNode).Temp, state->dataLoopNodes->Node(state->dataZoneEquip->ZoneEquipConfig(i).ZoneNode).HumRat); diff --git a/tst/EnergyPlus/unit/PurchasedAirManager.unit.cc b/tst/EnergyPlus/unit/PurchasedAirManager.unit.cc index a2d56abc958..1f55b00646e 100644 --- a/tst/EnergyPlus/unit/PurchasedAirManager.unit.cc +++ b/tst/EnergyPlus/unit/PurchasedAirManager.unit.cc @@ -72,6 +72,7 @@ #include #include #include +#include using namespace EnergyPlus; using namespace EnergyPlus::DataHeatBalance; @@ -116,15 +117,13 @@ class ZoneIdealLoadsTest : public EnergyPlusFixture state->dataZoneEnergyDemand->ZoneSysEnergyDemand(1).OutputRequiredToHeatingSP = 1000.0; state->dataZoneEnergyDemand->ZoneSysEnergyDemand(1).OutputRequiredToCoolingSP = 2000.0; state->dataZoneEnergyDemand->ZoneSysMoistureDemand.allocate(1); - state->dataHeatBalFanSys->NonAirSystemResponse.allocate(1); - state->dataHeatBalFanSys->SysDepZoneLoads.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); state->dataHeatBal->MassConservation.allocate(1); state->dataHeatBal->ZoneIntGain.allocate(1); state->dataHeatBal->spaceIntGain.allocate(1); state->dataHeatBal->spaceIntGainDevices.allocate(1); state->dataSurface->SurfaceWindow.allocate(1); state->dataHeatBal->RefrigCaseCredit.allocate(1); - state->dataHeatBalFanSys->ZoneLatentGain.allocate(1); state->dataHeatBalFanSys->TempControlType.allocate(1); state->dataHeatBalFanSys->TempControlType(1) = DataHVACGlobals::ThermostatType::SingleHeating; @@ -132,8 +131,7 @@ class ZoneIdealLoadsTest : public EnergyPlusFixture state->dataZoneEnergyDemand->DeadBandOrSetback.allocate(1); state->dataZoneEnergyDemand->DeadBandOrSetback(1) = false; - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.07; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.07; state->dataZoneEquip->ZoneEquipInputsFilled = false; } @@ -397,8 +395,8 @@ TEST_F(ZoneIdealLoadsTest, IdealLoads_PlenumTest) bool ErrorsFound = false; GetZoneData(*state, ErrorsFound); - state->dataHeatBal->Zone(1).HTSurfaceFirst = 1; - state->dataHeatBal->Zone(1).HTSurfaceLast = 1; + state->dataHeatBal->space(1).HTSurfaceFirst = 1; + state->dataHeatBal->space(1).HTSurfaceLast = 1; state->dataScheduleMgr->Schedule.allocate(1); AllocateHeatBalArrays(*state); @@ -509,8 +507,8 @@ TEST_F(ZoneIdealLoadsTest, IdealLoads_ExhaustNodeTest) bool ErrorsFound = false; GetZoneData(*state, ErrorsFound); - state->dataHeatBal->Zone(1).HTSurfaceFirst = 1; - state->dataHeatBal->Zone(1).HTSurfaceLast = 1; + state->dataHeatBal->space(1).HTSurfaceFirst = 1; + state->dataHeatBal->space(1).HTSurfaceLast = 1; state->dataScheduleMgr->Schedule.allocate(1); AllocateHeatBalArrays(*state); EXPECT_FALSE(ErrorsFound); // expect no errors @@ -631,8 +629,8 @@ TEST_F(ZoneIdealLoadsTest, IdealLoads_IntermediateOutputVarsTest) bool ErrorsFound = false; GetZoneData(*state, ErrorsFound); - state->dataHeatBal->Zone(1).HTSurfaceFirst = 1; - state->dataHeatBal->Zone(1).HTSurfaceLast = 1; + state->dataHeatBal->space(1).HTSurfaceFirst = 1; + state->dataHeatBal->space(1).HTSurfaceLast = 1; state->dataScheduleMgr->Schedule.allocate(1); AllocateHeatBalArrays(*state); EXPECT_FALSE(ErrorsFound); // expect no errors @@ -801,8 +799,8 @@ TEST_F(ZoneIdealLoadsTest, IdealLoads_EMSOverrideTest) bool ErrorsFound = false; GetZoneData(*state, ErrorsFound); - state->dataHeatBal->Zone(1).HTSurfaceFirst = 1; - state->dataHeatBal->Zone(1).HTSurfaceLast = 1; + state->dataHeatBal->space(1).HTSurfaceFirst = 1; + state->dataHeatBal->space(1).HTSurfaceLast = 1; state->dataScheduleMgr->Schedule.allocate(1); AllocateHeatBalArrays(*state); EXPECT_FALSE(ErrorsFound); // expect no errors @@ -909,8 +907,8 @@ TEST_F(ZoneIdealLoadsTest, IdealLoads_NoCapacityTest) bool ErrorsFound = false; GetZoneData(*state, ErrorsFound); - state->dataHeatBal->Zone(1).HTSurfaceFirst = 1; - state->dataHeatBal->Zone(1).HTSurfaceLast = 1; + state->dataHeatBal->space(1).HTSurfaceFirst = 1; + state->dataHeatBal->space(1).HTSurfaceLast = 1; state->dataScheduleMgr->Schedule.allocate(1); AllocateHeatBalArrays(*state); EXPECT_FALSE(ErrorsFound); // expect no errors @@ -1057,8 +1055,8 @@ TEST_F(ZoneIdealLoadsTest, IdealLoads_EMSOverrideTest_Revised) bool ErrorsFound = false; GetZoneData(*state, ErrorsFound); - state->dataHeatBal->Zone(1).HTSurfaceFirst = 1; - state->dataHeatBal->Zone(1).HTSurfaceLast = 1; + state->dataHeatBal->space(1).HTSurfaceFirst = 1; + state->dataHeatBal->space(1).HTSurfaceLast = 1; state->dataScheduleMgr->Schedule.allocate(1); AllocateHeatBalArrays(*state); EXPECT_FALSE(ErrorsFound); // expect no errors @@ -1228,8 +1226,8 @@ TEST_F(ZoneIdealLoadsTest, IdealLoads_EMSOverrideTest_Revised_ZeroFlow) bool ErrorsFound = false; GetZoneData(*state, ErrorsFound); - state->dataHeatBal->Zone(1).HTSurfaceFirst = 1; - state->dataHeatBal->Zone(1).HTSurfaceLast = 1; + state->dataHeatBal->space(1).HTSurfaceFirst = 1; + state->dataHeatBal->space(1).HTSurfaceLast = 1; state->dataScheduleMgr->Schedule.allocate(1); AllocateHeatBalArrays(*state); EXPECT_FALSE(ErrorsFound); // expect no errors @@ -1401,8 +1399,6 @@ TEST_F(ZoneIdealLoadsTest, IdealLoads_Fix_SA_HumRat_Test) bool ErrorsFound = false; GetZoneData(*state, ErrorsFound); - state->dataHeatBal->Zone(1).HTSurfaceFirst = 1; - state->dataHeatBal->Zone(1).HTSurfaceLast = 1; state->dataScheduleMgr->Schedule.allocate(1); AllocateHeatBalArrays(*state); EXPECT_FALSE(ErrorsFound); // expect no errors diff --git a/tst/EnergyPlus/unit/RoomAirflowNetwork.unit.cc b/tst/EnergyPlus/unit/RoomAirflowNetwork.unit.cc index 79e4abab930..2f25cc9e6c1 100644 --- a/tst/EnergyPlus/unit/RoomAirflowNetwork.unit.cc +++ b/tst/EnergyPlus/unit/RoomAirflowNetwork.unit.cc @@ -75,6 +75,7 @@ #include #include #include +#include using namespace EnergyPlus; using namespace DataEnvironment; @@ -127,8 +128,7 @@ class RoomAirflowNetworkTest : public EnergyPlusFixture state->dataMstBal->RhoVaporSurfIn.allocate(NumOfSurfaces); state->dataMstBal->RhoVaporAirIn.allocate(NumOfSurfaces); state->dataMstBal->HMassConvInFD.allocate(NumOfSurfaces); - state->dataHeatBalFanSys->MAT.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(state->dataGlobal->NumOfZones); state->afn->AirflowNetworkLinkageData.allocate(5); state->afn->AirflowNetworkNodeSimu.allocate(6); state->afn->AirflowNetworkLinkSimu.allocate(5); @@ -263,8 +263,9 @@ TEST_F(RoomAirflowNetworkTest, RAFNTest) state->dataHeatBal->Zone(ZoneNum).Volume = 100; state->dataHeatBal->Zone(ZoneNum).IsControlled = true; - state->dataHeatBal->Zone(ZoneNum).HTSurfaceFirst = 1; - state->dataHeatBal->Zone(ZoneNum).HTSurfaceLast = 2; + state->dataHeatBal->space.allocate(ZoneNum); + state->dataHeatBal->space(ZoneNum).HTSurfaceFirst = 1; + state->dataHeatBal->space(ZoneNum).HTSurfaceLast = 2; state->dataHeatBal->Zone(ZoneNum).ZoneVolCapMultpMoist = 0; state->dataHeatBal->Zone(ZoneNum).spaceIndexes.emplace_back(1); @@ -291,33 +292,27 @@ TEST_F(RoomAirflowNetworkTest, RAFNTest) state->dataLoopNodes->NodeID(1) = "Supply"; state->dataLoopNodes->NodeID(2) = "Return"; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.001; - state->dataLoopNodes->Node(1).Temp = 20.0; state->dataLoopNodes->Node(1).HumRat = 0.001; state->dataLoopNodes->Node(1).MassFlowRate = 0.01; - state->dataHeatBalFanSys->MAT(1) = 20.0; + auto &thisZoneHB = state->dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); + thisZoneHB.MAT = 20.0; + thisZoneHB.ZoneAirHumRat = 0.001; state->dataHeatBalSurf->SurfHConvInt(1) = 1.0; state->dataHeatBalSurf->SurfHConvInt(2) = 1.0; state->dataHeatBalSurf->SurfTempInTmp(1) = 25.0; state->dataHeatBalSurf->SurfTempInTmp(2) = 30.0; - state->dataMstBal->RhoVaporAirIn(1) = - PsyRhovFnTdbWPb(state->dataHeatBalFanSys->MAT(ZoneNum), state->dataHeatBalFanSys->ZoneAirHumRat(ZoneNum), state->dataEnvrn->OutBaroPress); - state->dataMstBal->RhoVaporAirIn(2) = - PsyRhovFnTdbWPb(state->dataHeatBalFanSys->MAT(ZoneNum), state->dataHeatBalFanSys->ZoneAirHumRat(ZoneNum), state->dataEnvrn->OutBaroPress); + state->dataMstBal->RhoVaporAirIn(1) = PsyRhovFnTdbWPb(thisZoneHB.MAT, thisZoneHB.ZoneAirHumRat, state->dataEnvrn->OutBaroPress); + state->dataMstBal->RhoVaporAirIn(2) = PsyRhovFnTdbWPb(thisZoneHB.MAT, thisZoneHB.ZoneAirHumRat, state->dataEnvrn->OutBaroPress); state->dataMstBal->HMassConvInFD(1) = state->dataHeatBalSurf->SurfHConvInt(1) / - ((PsyRhoAirFnPbTdbW( - *state, state->dataEnvrn->OutBaroPress, state->dataHeatBalFanSys->MAT(ZoneNum), state->dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)) + - state->dataMstBal->RhoVaporAirIn(1)) * - PsyCpAirFnW(state->dataHeatBalFanSys->ZoneAirHumRat(ZoneNum))); + ((PsyRhoAirFnPbTdbW(*state, state->dataEnvrn->OutBaroPress, thisZoneHB.MAT, thisZoneHB.ZoneAirHumRat) + state->dataMstBal->RhoVaporAirIn(1)) * + PsyCpAirFnW(thisZoneHB.ZoneAirHumRat)); state->dataMstBal->HMassConvInFD(2) = state->dataHeatBalSurf->SurfHConvInt(2) / - ((PsyRhoAirFnPbTdbW( - *state, state->dataEnvrn->OutBaroPress, state->dataHeatBalFanSys->MAT(ZoneNum), state->dataHeatBalFanSys->ZoneAirHumRat(ZoneNum)) + - state->dataMstBal->RhoVaporAirIn(2)) * - PsyCpAirFnW(state->dataHeatBalFanSys->ZoneAirHumRat(ZoneNum))); + ((PsyRhoAirFnPbTdbW(*state, state->dataEnvrn->OutBaroPress, thisZoneHB.MAT, thisZoneHB.ZoneAirHumRat) + state->dataMstBal->RhoVaporAirIn(2)) * + PsyCpAirFnW(thisZoneHB.ZoneAirHumRat)); RoomAirNode = 1; auto &thisRAFN(state->dataRoomAirflowNetModel->RAFN(ZoneNum)); diff --git a/tst/EnergyPlus/unit/SecondaryDXCoils.unit.cc b/tst/EnergyPlus/unit/SecondaryDXCoils.unit.cc index 394b452b5d2..6b682e393fa 100644 --- a/tst/EnergyPlus/unit/SecondaryDXCoils.unit.cc +++ b/tst/EnergyPlus/unit/SecondaryDXCoils.unit.cc @@ -61,9 +61,9 @@ #include #include #include -#include #include #include +#include using namespace EnergyPlus; using namespace DXCoils; @@ -86,6 +86,8 @@ TEST_F(EnergyPlusFixture, SecondaryDXCoolingCoilSingleSpeed_Test1) state->dataDXCoils->DXCoil(DXCoilNum).TotalCoolingEnergyRate = 5000.0; state->dataDXCoils->DXCoil(DXCoilNum).ElecCoolingPower = 500.0; state->dataDXCoils->DXCoil(DXCoilNum).SecCoilSensibleHeatGainRate = 0.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataDXCoils->DXCoil(DXCoilNum).SecZonePtr = 1; CalcSecondaryDXCoils(*state, DXCoilNum); EXPECT_DOUBLE_EQ(5500.0, state->dataDXCoils->DXCoil(DXCoilNum).SecCoilSensibleHeatGainRate); @@ -107,6 +109,8 @@ TEST_F(EnergyPlusFixture, SecondaryDXCoolingCoilTwoSpeed_Test2) state->dataDXCoils->DXCoil(DXCoilNum).TotalCoolingEnergyRate = 5000.0; state->dataDXCoils->DXCoil(DXCoilNum).ElecCoolingPower = 500.0; state->dataDXCoils->DXCoil(DXCoilNum).SecCoilSensibleHeatGainRate = 0.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataDXCoils->DXCoil(DXCoilNum).SecZonePtr = 1; CalcSecondaryDXCoils(*state, DXCoilNum); EXPECT_DOUBLE_EQ(5500.0, state->dataDXCoils->DXCoil(DXCoilNum).SecCoilSensibleHeatGainRate); @@ -128,6 +132,8 @@ TEST_F(EnergyPlusFixture, SecondaryDXCoolingCoilMultiSpeed_Test3) state->dataDXCoils->DXCoil(DXCoilNum).TotalCoolingEnergyRate = 5000.0; state->dataDXCoils->DXCoil(DXCoilNum).ElecCoolingPower = 500.0; state->dataDXCoils->DXCoil(DXCoilNum).SecCoilSensibleHeatGainRate = 0.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataDXCoils->DXCoil(DXCoilNum).SecZonePtr = 1; CalcSecondaryDXCoils(*state, DXCoilNum); EXPECT_DOUBLE_EQ(5500.0, state->dataDXCoils->DXCoil(DXCoilNum).SecCoilSensibleHeatGainRate); @@ -154,10 +160,9 @@ TEST_F(EnergyPlusFixture, SecondaryDXHeatingCoilSingleSpeed_Test4) state->dataDXCoils->DXCoil(DXCoilNum).SecZonePtr = 1; state->dataLoopNodes->Node.allocate(2); - state->dataHeatBalFanSys->ZT.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); - state->dataHeatBalFanSys->ZT(1) = 10.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.003; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZT = 10.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.003; state->dataDXCoils->DXCoil(DXCoilNum).SecCoilAirFlow = 1.0; state->dataDXCoils->DXCoil(DXCoilNum).CompressorPartLoadRatio = 1.0; state->dataDXCoils->DXCoil(DXCoilNum).SecCoilRatedSHR = 1.0; @@ -236,10 +241,9 @@ TEST_F(EnergyPlusFixture, SecondaryDXHeatingCoilMultiSpeed_Test5) state->dataDXCoils->DXCoil(DXCoilNum).SecZonePtr = 1; state->dataLoopNodes->Node.allocate(2); - state->dataHeatBalFanSys->ZT.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); - state->dataHeatBalFanSys->ZT(1) = 10.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.003; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZT = 10.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.003; state->dataDXCoils->DXCoil(DXCoilNum).MSSecCoilAirFlow(1) = 1.0; state->dataDXCoils->DXCoil(DXCoilNum).MSSecCoilAirFlow(2) = 1.0; state->dataDXCoils->DXCoil(DXCoilNum).MSSecCoilSHRFT(1) = 0; diff --git a/tst/EnergyPlus/unit/SolarShading.unit.cc b/tst/EnergyPlus/unit/SolarShading.unit.cc index fd9d06797b7..33182861eed 100644 --- a/tst/EnergyPlus/unit/SolarShading.unit.cc +++ b/tst/EnergyPlus/unit/SolarShading.unit.cc @@ -70,6 +70,7 @@ #include #include #include +#include using namespace EnergyPlus; using namespace EnergyPlus::SolarShading; @@ -2707,9 +2708,13 @@ TEST_F(EnergyPlusFixture, WindowShadingManager_Lum_Test) surf2.activeWindowShadingControl = surf2.windowShadingControlList[SolarShading::selectActiveWindowShadingControlIndex(*state, 2)]; state->dataHeatBal->Zone.allocate(1); - state->dataHeatBal->Zone(1).WindowSurfaceFirst = 1; - state->dataHeatBal->Zone(1).WindowSurfaceLast = 2; + state->dataHeatBal->Zone(1).spaceIndexes.allocate(1); + state->dataHeatBal->Zone(1).spaceIndexes[0] = 1; + state->dataHeatBal->space.allocate(1); + state->dataHeatBal->space(1).WindowSurfaceFirst = 1; + state->dataHeatBal->space(1).WindowSurfaceLast = 2; state->dataGlobal->NumOfZones = 1; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(state->dataGlobal->NumOfZones); // the following enables calculation when sun is up with SolarOnWindow computed to be 3700 int constexpr NumTimeSteps(6); diff --git a/tst/EnergyPlus/unit/SurfaceGeometry.unit.cc b/tst/EnergyPlus/unit/SurfaceGeometry.unit.cc index f6ff6a97215..6be23fc350e 100644 --- a/tst/EnergyPlus/unit/SurfaceGeometry.unit.cc +++ b/tst/EnergyPlus/unit/SurfaceGeometry.unit.cc @@ -2476,7 +2476,9 @@ TEST_F(EnergyPlusFixture, CalculateZoneVolume_SimpleBox_test) enteredCeilingHeight.dimension(state->dataGlobal->NumOfZones, false); state->dataHeatBal->Zone.allocate(state->dataGlobal->NumOfZones); state->dataHeatBal->Zone(1).HasFloor = true; - state->dataHeatBal->Zone(1).HTSurfaceFirst = 1; + state->dataHeatBal->space.allocate(1); + state->dataHeatBal->Zone(1).spaceIndexes.emplace_back(1); + state->dataHeatBal->space(1).HTSurfaceFirst = 1; state->dataHeatBal->Zone(1).AllSurfaceFirst = 1; state->dataHeatBal->Zone(1).AllSurfaceLast = 6; @@ -2612,7 +2614,9 @@ TEST_F(EnergyPlusFixture, CalculateZoneVolume_BoxNoCeiling_test) enteredCeilingHeight.dimension(state->dataGlobal->NumOfZones, false); state->dataHeatBal->Zone.allocate(state->dataGlobal->NumOfZones); state->dataHeatBal->Zone(1).HasFloor = true; - state->dataHeatBal->Zone(1).HTSurfaceFirst = 1; + state->dataHeatBal->space.allocate(1); + state->dataHeatBal->Zone(1).spaceIndexes.emplace_back(1); + state->dataHeatBal->space(1).HTSurfaceFirst = 1; state->dataHeatBal->Zone(1).AllSurfaceFirst = 1; state->dataHeatBal->Zone(1).AllSurfaceLast = 5; @@ -2677,7 +2681,9 @@ TEST_F(EnergyPlusFixture, CalculateZoneVolume_BoxNoFloor_test) enteredCeilingHeight.dimension(state->dataGlobal->NumOfZones, false); state->dataHeatBal->Zone.allocate(state->dataGlobal->NumOfZones); state->dataHeatBal->Zone(1).HasFloor = true; - state->dataHeatBal->Zone(1).HTSurfaceFirst = 1; + state->dataHeatBal->space.allocate(1); + state->dataHeatBal->Zone(1).spaceIndexes.emplace_back(1); + state->dataHeatBal->space(1).HTSurfaceFirst = 1; state->dataHeatBal->Zone(1).AllSurfaceFirst = 1; state->dataHeatBal->Zone(1).AllSurfaceLast = 5; @@ -2741,7 +2747,9 @@ TEST_F(EnergyPlusFixture, CalculateZoneVolume_BoxNoCeilingFloor_test) state->dataGlobal->NumOfZones = 1; enteredCeilingHeight.dimension(state->dataGlobal->NumOfZones, false); state->dataHeatBal->Zone.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBal->Zone(1).HTSurfaceFirst = 1; + state->dataHeatBal->space.allocate(1); + state->dataHeatBal->Zone(1).spaceIndexes.emplace_back(1); + state->dataHeatBal->space(1).HTSurfaceFirst = 1; state->dataHeatBal->Zone(1).AllSurfaceFirst = 1; state->dataHeatBal->Zone(1).AllSurfaceLast = 4; @@ -5739,15 +5747,15 @@ TEST_F(EnergyPlusFixture, HeatBalanceIntRadExchange_SetupEnclosuresWithAirBounda EXPECT_EQ(state->dataHeatBal->Zone(1).AllSurfaceFirst + 1, Zone1Surface1); // air boundary surface EXPECT_EQ(state->dataHeatBal->Zone(2).AllSurfaceFirst, Zone2Surface1); // no air boundary surfaces in Zone 2 EXPECT_EQ(state->dataHeatBal->Zone(3).AllSurfaceFirst, Zone3Surface1); // air boundary surface - EXPECT_EQ(state->dataHeatBal->Zone(1).HTSurfaceFirst, Zone1Surface1); // first non-air boundary surface - EXPECT_EQ(state->dataHeatBal->Zone(2).HTSurfaceFirst, Zone2Surface1); // first non-air boundary surface - EXPECT_EQ(state->dataHeatBal->Zone(3).HTSurfaceFirst, Zone3Floor); // first non-air boundary surface + EXPECT_EQ(state->dataHeatBal->space(1).HTSurfaceFirst, Zone1Surface1); // first non-air boundary surface + EXPECT_EQ(state->dataHeatBal->space(2).HTSurfaceFirst, Zone2Surface1); // first non-air boundary surface + EXPECT_EQ(state->dataHeatBal->space(3).HTSurfaceFirst, Zone3Floor); // first non-air boundary surface EXPECT_EQ(state->dataHeatBal->Zone(1).AllSurfaceLast, Zone1Floor); EXPECT_EQ(state->dataHeatBal->Zone(2).AllSurfaceLast, Zone2Floor); EXPECT_EQ(state->dataHeatBal->Zone(3).AllSurfaceLast, Zone3Floor); - EXPECT_EQ(state->dataHeatBal->Zone(1).HTSurfaceLast, Zone1Floor); - EXPECT_EQ(state->dataHeatBal->Zone(2).HTSurfaceLast, Zone2Floor); - EXPECT_EQ(state->dataHeatBal->Zone(3).HTSurfaceLast, Zone3Floor); + EXPECT_EQ(state->dataHeatBal->space(1).HTSurfaceLast, Zone1Floor); + EXPECT_EQ(state->dataHeatBal->space(2).HTSurfaceLast, Zone2Floor); + EXPECT_EQ(state->dataHeatBal->space(3).HTSurfaceLast, Zone3Floor); } TEST_F(EnergyPlusFixture, HeatBalanceIntRadExchange_SetupEnclosuresWithAirBoundaries3) @@ -8678,12 +8686,12 @@ TEST_F(EnergyPlusFixture, GetSurfaceData_SurfaceOrder) EXPECT_EQ(windowEastWindow, 16); EXPECT_EQ(windowSouthWindow, 17); EXPECT_EQ(windowWestWindow, 18); - EXPECT_EQ(state->dataHeatBal->Zone(1).HTSurfaceFirst, 7); - EXPECT_EQ(state->dataHeatBal->Zone(1).HTSurfaceLast, 19); - EXPECT_EQ(state->dataHeatBal->Zone(1).OpaqOrIntMassSurfaceFirst, 7); - EXPECT_EQ(state->dataHeatBal->Zone(1).OpaqOrIntMassSurfaceLast, 14); - EXPECT_EQ(state->dataHeatBal->Zone(1).WindowSurfaceFirst, 15); - EXPECT_EQ(state->dataHeatBal->Zone(1).WindowSurfaceLast, 19); + EXPECT_EQ(state->dataHeatBal->space(1).HTSurfaceFirst, 7); + EXPECT_EQ(state->dataHeatBal->space(1).HTSurfaceLast, 19); + EXPECT_EQ(state->dataHeatBal->space(1).OpaqOrIntMassSurfaceFirst, 7); + EXPECT_EQ(state->dataHeatBal->space(1).OpaqOrIntMassSurfaceLast, 14); + EXPECT_EQ(state->dataHeatBal->space(1).WindowSurfaceFirst, 15); + EXPECT_EQ(state->dataHeatBal->space(1).WindowSurfaceLast, 19); // GARAGE ZONE: int wallGarageInterior = UtilityRoutines::FindItemInList(UtilityRoutines::MakeUPPERCase("Garage:Interior"), state->dataSurface->Surface); @@ -8701,12 +8709,12 @@ TEST_F(EnergyPlusFixture, GetSurfaceData_SurfaceOrder) EXPECT_EQ(floorGarageFloor, 24); EXPECT_EQ(ceilingGarageInterior, 25); EXPECT_EQ(intmassEVChargingStation, 26); - EXPECT_EQ(state->dataHeatBal->Zone(2).HTSurfaceFirst, 20); - EXPECT_EQ(state->dataHeatBal->Zone(2).HTSurfaceLast, 26); - EXPECT_EQ(state->dataHeatBal->Zone(2).OpaqOrIntMassSurfaceFirst, 20); - EXPECT_EQ(state->dataHeatBal->Zone(2).OpaqOrIntMassSurfaceLast, 26); - EXPECT_EQ(state->dataHeatBal->Zone(2).WindowSurfaceFirst, 0); - EXPECT_EQ(state->dataHeatBal->Zone(2).WindowSurfaceLast, -1); + EXPECT_EQ(state->dataHeatBal->space(2).HTSurfaceFirst, 20); + EXPECT_EQ(state->dataHeatBal->space(2).HTSurfaceLast, 26); + EXPECT_EQ(state->dataHeatBal->space(2).OpaqOrIntMassSurfaceFirst, 20); + EXPECT_EQ(state->dataHeatBal->space(2).OpaqOrIntMassSurfaceLast, 26); + EXPECT_EQ(state->dataHeatBal->space(2).WindowSurfaceFirst, 0); + EXPECT_EQ(state->dataHeatBal->space(2).WindowSurfaceLast, -1); // ATTIC ZONE: int wallEastGable = UtilityRoutines::FindItemInList(UtilityRoutines::MakeUPPERCase("EastGable"), state->dataSurface->Surface); @@ -8739,15 +8747,15 @@ TEST_F(EnergyPlusFixture, GetSurfaceData_SurfaceOrder) EXPECT_EQ(roofWestRoof, 38); EXPECT_EQ(nonwindowTubularDaylightingDome1, 40); EXPECT_EQ(windowAtticSkylight, 39); - EXPECT_EQ(state->dataHeatBal->Zone(3).HTSurfaceFirst, wallEastGable); - EXPECT_EQ(state->dataHeatBal->Zone(3).HTSurfaceLast, nonwindowTubularDaylightingDome1); - EXPECT_EQ(state->dataHeatBal->Zone(3).OpaqOrIntMassSurfaceFirst, wallEastGable); - EXPECT_EQ(state->dataHeatBal->Zone(3).OpaqOrIntMassSurfaceLast, roofWestRoof); - EXPECT_EQ(state->dataHeatBal->Zone(3).WindowSurfaceFirst, windowAtticSkylight); - EXPECT_EQ(state->dataHeatBal->Zone(3).WindowSurfaceLast, windowAtticSkylight); - EXPECT_EQ(state->dataHeatBal->Zone(3).OpaqOrWinSurfaceLast, windowAtticSkylight); - EXPECT_EQ(state->dataHeatBal->Zone(3).TDDDomeFirst, nonwindowTubularDaylightingDome1); - EXPECT_EQ(state->dataHeatBal->Zone(3).TDDDomeLast, nonwindowTubularDaylightingDome1); + EXPECT_EQ(state->dataHeatBal->space(3).HTSurfaceFirst, wallEastGable); + EXPECT_EQ(state->dataHeatBal->space(3).HTSurfaceLast, nonwindowTubularDaylightingDome1); + EXPECT_EQ(state->dataHeatBal->space(3).OpaqOrIntMassSurfaceFirst, wallEastGable); + EXPECT_EQ(state->dataHeatBal->space(3).OpaqOrIntMassSurfaceLast, roofWestRoof); + EXPECT_EQ(state->dataHeatBal->space(3).WindowSurfaceFirst, windowAtticSkylight); + EXPECT_EQ(state->dataHeatBal->space(3).WindowSurfaceLast, windowAtticSkylight); + EXPECT_EQ(state->dataHeatBal->space(3).OpaqOrWinSurfaceLast, windowAtticSkylight); + EXPECT_EQ(state->dataHeatBal->space(3).TDDDomeFirst, nonwindowTubularDaylightingDome1); + EXPECT_EQ(state->dataHeatBal->space(3).TDDDomeLast, nonwindowTubularDaylightingDome1); // Reporting (legacy) Order (zero-based) // SHADING SURFACES: diff --git a/tst/EnergyPlus/unit/SystemAvailabilityManager.unit.cc b/tst/EnergyPlus/unit/SystemAvailabilityManager.unit.cc index c769c3813b5..bbcb6b3ca0b 100644 --- a/tst/EnergyPlus/unit/SystemAvailabilityManager.unit.cc +++ b/tst/EnergyPlus/unit/SystemAvailabilityManager.unit.cc @@ -447,7 +447,7 @@ TEST_F(EnergyPlusFixture, SysAvailManager_HybridVentilation_OT_CO2Control) state->dataHVACGlobal->HybridVentSysAvailVentCtrl.allocate(1); state->dataAirLoop->PriAirSysAvailMgr.allocate(1); state->dataHeatBal->Zone.allocate(1); - state->dataHeatBalFanSys->MAT.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); state->dataHeatBal->ZoneMRT.allocate(1); state->dataContaminantBalance->ZoneAirCO2.allocate(1); state->dataContaminantBalance->ZoneCO2SetPoint.allocate(1); @@ -483,24 +483,24 @@ TEST_F(EnergyPlusFixture, SysAvailManager_HybridVentilation_OT_CO2Control) state->dataSystemAvailabilityManager->HybridVentData(1).ControlMode = 5; // 80% acceptance state->dataThermalComforts->runningAverageASH = 20.0; - state->dataHeatBalFanSys->MAT(1) = 23.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 23.0; state->dataHeatBal->ZoneMRT(1) = 27.0; SystemAvailabilityManager::CalcHybridVentSysAvailMgr(*state, 1, 1); EXPECT_EQ(1, state->dataSystemAvailabilityManager->HybridVentData(1).VentilationCtrl); // Vent open - state->dataHeatBalFanSys->MAT(1) = 26.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 26.0; state->dataHeatBal->ZoneMRT(1) = 30.0; SystemAvailabilityManager::CalcHybridVentSysAvailMgr(*state, 1, 1); EXPECT_EQ(2, state->dataSystemAvailabilityManager->HybridVentData(1).VentilationCtrl); // System operation state->dataSystemAvailabilityManager->HybridVentData(1).ControlMode = 6; // 90% acceptance - state->dataHeatBalFanSys->MAT(1) = 23.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 23.0; state->dataHeatBal->ZoneMRT(1) = 27.0; SystemAvailabilityManager::CalcHybridVentSysAvailMgr(*state, 1, 1); EXPECT_EQ(1, state->dataSystemAvailabilityManager->HybridVentData(1).VentilationCtrl); // Vent open - state->dataHeatBalFanSys->MAT(1) = 26.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 26.0; state->dataHeatBal->ZoneMRT(1) = 30.0; SystemAvailabilityManager::CalcHybridVentSysAvailMgr(*state, 1, 1); EXPECT_EQ(2, state->dataSystemAvailabilityManager->HybridVentData(1).VentilationCtrl); // System operation @@ -564,21 +564,6 @@ TEST_F(EnergyPlusFixture, SysAvailManager_HybridVentilation_OT_CO2Control) state->dataHeatBalFanSys->TempZoneThermostatSetPoint(1) = 25.0; SystemAvailabilityManager::CalcHybridVentSysAvailMgr(*state, 1, 1); EXPECT_EQ(1, state->dataSystemAvailabilityManager->HybridVentData(1).VentilationCtrl); // Can change - - state->dataSystemAvailabilityManager->HybridVentData.deallocate(); - state->dataHVACGlobal->HybridVentSysAvailVentCtrl.deallocate(); - state->dataAirLoop->PriAirSysAvailMgr.deallocate(); - state->dataHeatBal->Zone.deallocate(); - state->dataHeatBalFanSys->MAT.deallocate(); - state->dataHeatBal->ZoneMRT.deallocate(); - state->dataContaminantBalance->ZoneAirCO2.deallocate(); - state->dataContaminantBalance->ZoneCO2SetPoint.deallocate(); - state->dataAirLoop->PriAirSysAvailMgr.deallocate(); - state->dataSystemAvailabilityManager->SchedData.deallocate(); - state->dataScheduleMgr->Schedule.deallocate(); - state->dataHVACGlobal->ZoneComp.deallocate(); - state->dataHeatBalFanSys->TempControlType.deallocate(); - state->dataHeatBalFanSys->TempZoneThermostatSetPoint.deallocate(); } TEST_F(EnergyPlusFixture, SysAvailManager_NightCycleGetInput) diff --git a/tst/EnergyPlus/unit/ThermalChimney.unit.cc b/tst/EnergyPlus/unit/ThermalChimney.unit.cc index eaee80e6900..e547748ea17 100644 --- a/tst/EnergyPlus/unit/ThermalChimney.unit.cc +++ b/tst/EnergyPlus/unit/ThermalChimney.unit.cc @@ -56,7 +56,6 @@ #include #include #include -#include #include #include #include @@ -71,12 +70,12 @@ #include #include #include +#include using namespace EnergyPlus; using namespace EnergyPlus::DataEnvironment; using namespace EnergyPlus::DataHeatBalance; using namespace EnergyPlus::DataHVACGlobals; -using namespace EnergyPlus::DataHeatBalFanSys; using namespace EnergyPlus::InternalHeatGains; using namespace EnergyPlus::HeatBalanceManager; using namespace EnergyPlus::OutputProcessor; @@ -1152,16 +1151,15 @@ TEST_F(EnergyPlusFixture, ThermalChimney_EMSAirflow_Test) state->dataHeatBalSurf->SurfTempIn(surfNum) = 26.99; surfNum = UtilityRoutines::FindItemInList("ZN004:WALL001:WIN001", state->dataSurface->Surface); state->dataHeatBalSurf->SurfTempIn(surfNum) = 22.99; - state->dataHeatBalFanSys->MAT.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->MAT = 23.0; - state->dataHeatBalFanSys->ZoneAirHumRat = 0.01; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(state->dataGlobal->NumOfZones); + for (auto &thisZoneHB : state->dataZoneTempPredictorCorrector->zoneHeatBalance) { + thisZoneHB.MAT = 23.0; + thisZoneHB.ZoneAirHumRat = 0.01; + } state->dataEnvrn->OutBaroPress = 101325.0; state->dataEnvrn->StdRhoAir = Psychrometrics::PsyRhoAirFnPbTdbW(*state, state->dataEnvrn->OutBaroPress, 20.0, 0.0); - state->dataHeatBalFanSys->MCPThermChim.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->ThermChimAMFL.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->MCPTThermChim.allocate(state->dataGlobal->NumOfZones); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(state->dataGlobal->NumOfZones); state->dataScheduleMgr->Schedule(1).CurrentValue = 1.0; state->dataHeatBal->ZnAirRpt.allocate(state->dataGlobal->NumOfZones); // No EMS diff --git a/tst/EnergyPlus/unit/ThermalComfort.unit.cc b/tst/EnergyPlus/unit/ThermalComfort.unit.cc index 0fcf9bad7af..34e0e98bb8b 100644 --- a/tst/EnergyPlus/unit/ThermalComfort.unit.cc +++ b/tst/EnergyPlus/unit/ThermalComfort.unit.cc @@ -92,7 +92,7 @@ TEST_F(EnergyPlusFixture, ThermalComfort_CalcIfSetPointMetTest1) state->dataHeatBalFanSys->TempControlType.allocate(1); state->dataRoomAirMod->AirModel.allocate(state->dataGlobal->NumOfZones); state->dataRoomAirMod->AirModel(1).AirModelType = DataRoomAirModel::RoomAirModel::Mixing; - state->dataHeatBalFanSys->ZTAV.allocate(state->dataGlobal->NumOfZones); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(state->dataGlobal->NumOfZones); state->dataHeatBalFanSys->ZoneThermostatSetPointLo.allocate(state->dataGlobal->NumOfZones); state->dataHeatBalFanSys->ZoneThermostatSetPointHi.allocate(state->dataGlobal->NumOfZones); state->dataGlobal->TimeStepZone = 0.25; @@ -105,7 +105,7 @@ TEST_F(EnergyPlusFixture, ThermalComfort_CalcIfSetPointMetTest1) state->dataHeatBalFanSys->TempControlType(1) = DataHVACGlobals::ThermostatType::SingleHeating; // heating - state->dataHeatBalFanSys->ZTAV(1) = 21.1; // 70F + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 21.1; // 70F state->dataHeatBalFanSys->ZoneThermostatSetPointLo(1) = 22.2; // 72F state->dataZoneEnergyDemand->ZoneSysEnergyDemand(1).TotalOutputRequired = 500.0; // must be greater than zero CalcIfSetPointMet(*state); @@ -115,7 +115,7 @@ TEST_F(EnergyPlusFixture, ThermalComfort_CalcIfSetPointMetTest1) EXPECT_EQ(0., state->dataThermalComforts->ThermalComfortSetPoint(1).notMetCoolingOccupied); // cooling - state->dataHeatBalFanSys->ZTAV(1) = 25.0; // 77F + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 25.0; // 77F state->dataHeatBalFanSys->ZoneThermostatSetPointHi(1) = 23.9; // 75F state->dataZoneEnergyDemand->ZoneSysEnergyDemand(1).TotalOutputRequired = -500.0; // must be less than zero CalcIfSetPointMet(*state); @@ -129,7 +129,7 @@ TEST_F(EnergyPlusFixture, ThermalComfort_CalcIfSetPointMetTest1) state->dataHeatBalFanSys->TempControlType(1) = DataHVACGlobals::ThermostatType::SingleCooling; // heating - state->dataHeatBalFanSys->ZTAV(1) = 21.1; // 70F + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 21.1; // 70F state->dataHeatBalFanSys->ZoneThermostatSetPointLo(1) = 22.2; // 72F state->dataZoneEnergyDemand->ZoneSysEnergyDemand(1).TotalOutputRequired = 500.0; // must be greater than zero CalcIfSetPointMet(*state); @@ -139,7 +139,7 @@ TEST_F(EnergyPlusFixture, ThermalComfort_CalcIfSetPointMetTest1) EXPECT_EQ(0., state->dataThermalComforts->ThermalComfortSetPoint(1).notMetCoolingOccupied); // cooling - state->dataHeatBalFanSys->ZTAV(1) = 25.0; // 77F + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 25.0; // 77F state->dataHeatBalFanSys->ZoneThermostatSetPointHi(1) = 23.9; // 75F state->dataZoneEnergyDemand->ZoneSysEnergyDemand(1).TotalOutputRequired = -500.0; // must be less than zero CalcIfSetPointMet(*state); @@ -153,7 +153,7 @@ TEST_F(EnergyPlusFixture, ThermalComfort_CalcIfSetPointMetTest1) state->dataHeatBalFanSys->TempControlType(1) = DataHVACGlobals::ThermostatType::SingleHeatCool; // heating - state->dataHeatBalFanSys->ZTAV(1) = 21.1; // 70F + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 21.1; // 70F state->dataHeatBalFanSys->ZoneThermostatSetPointLo(1) = 22.2; // 72F state->dataZoneEnergyDemand->ZoneSysEnergyDemand(1).TotalOutputRequired = 500.0; // must be greater than zero CalcIfSetPointMet(*state); @@ -163,7 +163,7 @@ TEST_F(EnergyPlusFixture, ThermalComfort_CalcIfSetPointMetTest1) EXPECT_EQ(0., state->dataThermalComforts->ThermalComfortSetPoint(1).notMetCoolingOccupied); // cooling - state->dataHeatBalFanSys->ZTAV(1) = 25.0; // 77F + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 25.0; // 77F state->dataHeatBalFanSys->ZoneThermostatSetPointHi(1) = 23.9; // 75F state->dataZoneEnergyDemand->ZoneSysEnergyDemand(1).TotalOutputRequired = -500.0; // must be less than zero CalcIfSetPointMet(*state); @@ -177,7 +177,7 @@ TEST_F(EnergyPlusFixture, ThermalComfort_CalcIfSetPointMetTest1) state->dataHeatBalFanSys->TempControlType(1) = DataHVACGlobals::ThermostatType::DualSetPointWithDeadBand; // heating - state->dataHeatBalFanSys->ZTAV(1) = 21.1; // 70F + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 21.1; // 70F state->dataHeatBalFanSys->ZoneThermostatSetPointLo(1) = 22.2; // 72F state->dataZoneEnergyDemand->ZoneSysEnergyDemand(1).TotalOutputRequired = 500.0; // must be greater than zero CalcIfSetPointMet(*state); @@ -187,7 +187,7 @@ TEST_F(EnergyPlusFixture, ThermalComfort_CalcIfSetPointMetTest1) EXPECT_EQ(0., state->dataThermalComforts->ThermalComfortSetPoint(1).notMetCoolingOccupied); // cooling - state->dataHeatBalFanSys->ZTAV(1) = 25.0; // 77F + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 25.0; // 77F state->dataHeatBalFanSys->ZoneThermostatSetPointHi(1) = 23.9; // 75F state->dataZoneEnergyDemand->ZoneSysEnergyDemand(1).TotalOutputRequired = -500.0; // must be less than zero CalcIfSetPointMet(*state); @@ -722,36 +722,36 @@ TEST_F(EnergyPlusFixture, ThermalComfort_CalcThermalComfortFanger) // compare_err_stream( "" ); - state->dataHeatBalFanSys->ZTAVComf(1) = 25.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAVComf = 25.0; state->dataHeatBal->ZoneMRT(1) = 26.0; - state->dataHeatBalFanSys->ZoneAirHumRatAvgComf(1) = 0.00529; // 0.002 to 0.006 + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvgComf = 0.00529; // 0.002 to 0.006 CalcThermalComfortFanger(*state); EXPECT_NEAR(state->dataThermalComforts->ThermalComfortData(1).FangerPMV, -1.262, 0.005); EXPECT_NEAR(state->dataThermalComforts->ThermalComfortData(1).FangerPPD, 38.3, 0.1); - state->dataHeatBalFanSys->ZTAVComf(1) = 26.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAVComf = 26.0; state->dataHeatBal->ZoneMRT(1) = 27.0; - state->dataHeatBalFanSys->ZoneAirHumRatAvgComf(1) = 0.00529; // 0.002 to 0.006 + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvgComf = 0.00529; // 0.002 to 0.006 CalcThermalComfortFanger(*state); EXPECT_NEAR(state->dataThermalComforts->ThermalComfortData(1).FangerPMV, -0.860, 0.005); EXPECT_NEAR(state->dataThermalComforts->ThermalComfortData(1).FangerPPD, 20.6, 0.1); - state->dataHeatBalFanSys->ZTAVComf(1) = 27.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAVComf = 27.0; state->dataHeatBal->ZoneMRT(1) = 28.0; - state->dataHeatBalFanSys->ZoneAirHumRatAvgComf(1) = 0.00529; // 0.002 to 0.006 + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvgComf = 0.00529; // 0.002 to 0.006 CalcThermalComfortFanger(*state); EXPECT_NEAR(state->dataThermalComforts->ThermalComfortData(1).FangerPMV, -0.460, 0.005); EXPECT_NEAR(state->dataThermalComforts->ThermalComfortData(1).FangerPPD, 9.4, 0.1); - state->dataHeatBalFanSys->ZTAVComf(1) = 25.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAVComf = 25.0; state->dataHeatBal->ZoneMRT(1) = 26.0; - state->dataHeatBalFanSys->ZoneAirHumRatAvgComf(1) = 0.00629; // 0.002 to 0.006 + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvgComf = 0.00629; // 0.002 to 0.006 CalcThermalComfortFanger(*state); @@ -773,6 +773,7 @@ TEST_F(EnergyPlusFixture, ThermalComfort_CalcSurfaceWeightedMRT) state->dataSurface->Surface.allocate(state->dataSurface->TotSurfaces); state->dataConstruction->Construct.allocate(state->dataSurface->TotSurfaces); state->dataHeatBal->Zone.allocate(1); + state->dataHeatBal->space.allocate(1); state->dataSurface->Surface(1).Area = 20.0; state->dataSurface->Surface(2).Area = 15.0; @@ -789,8 +790,9 @@ TEST_F(EnergyPlusFixture, ThermalComfort_CalcSurfaceWeightedMRT) state->dataSurface->Surface(1).Zone = 1; state->dataSurface->Surface(2).Zone = 1; state->dataSurface->Surface(3).Zone = 1; - state->dataHeatBal->Zone(1).HTSurfaceFirst = 1; - state->dataHeatBal->Zone(1).HTSurfaceLast = 3; + state->dataHeatBal->Zone(1).spaceIndexes.emplace_back(1); + state->dataHeatBal->space(1).HTSurfaceFirst = 1; + state->dataHeatBal->space(1).HTSurfaceLast = 3; state->dataHeatBalSurf->SurfInsideTempHist(1)(1) = 20.0; state->dataHeatBalSurf->SurfInsideTempHist(1)(2) = 15.0; state->dataHeatBalSurf->SurfInsideTempHist(1)(3) = 10.0; @@ -925,7 +927,7 @@ TEST_F(EnergyPlusFixture, ThermalComfort_CalcIfSetPointMetWithCutoutTest) state->dataHeatBalFanSys->TempControlType.allocate(1); state->dataRoomAirMod->AirModel.allocate(state->dataGlobal->NumOfZones); state->dataRoomAirMod->AirModel(1).AirModelType = DataRoomAirModel::RoomAirModel::Mixing; - state->dataHeatBalFanSys->ZTAV.allocate(state->dataGlobal->NumOfZones); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(state->dataGlobal->NumOfZones); state->dataHeatBalFanSys->ZoneThermostatSetPointLo.allocate(state->dataGlobal->NumOfZones); state->dataHeatBalFanSys->ZoneThermostatSetPointHi.allocate(state->dataGlobal->NumOfZones); state->dataHeatBalFanSys->ZoneThermostatSetPointLoAver.allocate(state->dataGlobal->NumOfZones); @@ -939,7 +941,7 @@ TEST_F(EnergyPlusFixture, ThermalComfort_CalcIfSetPointMetWithCutoutTest) state->dataHeatBalFanSys->TempControlType(1) = DataHVACGlobals::ThermostatType::DualSetPointWithDeadBand; // heating - state->dataHeatBalFanSys->ZTAV(1) = 21.1; // 70F + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 21.1; // 70F state->dataHeatBalFanSys->ZoneThermostatSetPointLo(1) = 22.2; // 72F state->dataHeatBalFanSys->ZoneThermostatSetPointLoAver(1) = 22.2; // 72F state->dataZoneEnergyDemand->ZoneSysEnergyDemand(1).TotalOutputRequired = 500.0; // must be greater than zero @@ -950,7 +952,7 @@ TEST_F(EnergyPlusFixture, ThermalComfort_CalcIfSetPointMetWithCutoutTest) EXPECT_EQ(0., state->dataThermalComforts->ThermalComfortSetPoint(1).notMetCoolingOccupied); // cooling - state->dataHeatBalFanSys->ZTAV(1) = 25.0; // 77F + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 25.0; // 77F state->dataHeatBalFanSys->ZoneThermostatSetPointHi(1) = 23.9; // 75F state->dataHeatBalFanSys->ZoneThermostatSetPointHiAver(1) = 23.9; // 75F state->dataZoneEnergyDemand->ZoneSysEnergyDemand(1).TotalOutputRequired = -500.0; // must be less than zero @@ -961,7 +963,7 @@ TEST_F(EnergyPlusFixture, ThermalComfort_CalcIfSetPointMetWithCutoutTest) EXPECT_EQ(state->dataGlobal->TimeStepZone, state->dataThermalComforts->ThermalComfortSetPoint(1).notMetCoolingOccupied); // no cooling or heating - state->dataHeatBalFanSys->ZTAV(1) = 23.0; // 73F + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 23.0; // 73F state->dataZoneEnergyDemand->ZoneSysEnergyDemand(1).TotalOutputRequired = 0.0; // must be zero CalcIfSetPointMet(*state); EXPECT_EQ(0, state->dataThermalComforts->ThermalComfortSetPoint(1).notMetHeating); @@ -983,9 +985,7 @@ TEST_F(EnergyPlusFixture, ThermalComfort_CalcThermalComfortASH55) state->dataThermalComforts->ThermalComfortData.allocate(state->dataHeatBal->TotPeople); state->dataGlobal->NumOfZones = 1; state->dataHeatBal->Zone.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->ZTAVComf.allocate(state->dataGlobal->NumOfZones); state->dataHeatBal->ZoneMRT.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->ZoneAirHumRatAvgComf.allocate(state->dataGlobal->NumOfZones); state->dataRoomAirMod->IsZoneDV.allocate(state->dataGlobal->NumOfZones); state->dataRoomAirMod->IsZoneUI.allocate(state->dataGlobal->NumOfZones); state->dataHeatBalFanSys->ZoneQdotRadHVACToPerson.allocate(state->dataGlobal->NumOfZones); @@ -1049,10 +1049,11 @@ TEST_F(EnergyPlusFixture, ThermalComfort_CalcThermalComfortASH55) Real64 ActMet = 1; Real64 CloUnit = 0.5; - state->dataHeatBalFanSys->ZTAVComf(1) = AirTemp; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(state->dataGlobal->NumOfZones); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAVComf = AirTemp; state->dataHeatBal->ZoneMRT(1) = RadTemp; - state->dataHeatBalFanSys->ZoneAirHumRatAvgComf(1) = - Psychrometrics::PsyWFnTdbRhPb(*state, state->dataHeatBalFanSys->ZTAVComf(1), RelHum, state->dataEnvrn->OutBaroPress); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvgComf = Psychrometrics::PsyWFnTdbRhPb( + *state, state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAVComf, RelHum, state->dataEnvrn->OutBaroPress); state->dataScheduleMgr->Schedule(1).CurrentValue = ActMet * BodySurfaceArea * ThermalComfort::ActLevelConv; state->dataScheduleMgr->Schedule(2).CurrentValue = CloUnit; @@ -1614,9 +1615,9 @@ TEST_F(EnergyPlusFixture, ThermalComfort_CalcThermalComfortFanger_Correct_TimeSt CalcThermalComfortFanger(*state); - EXPECT_NEAR(state->dataHeatBalFanSys->ZTAVComf(1), 14.863733439268286, 0.001); + EXPECT_NEAR(state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAVComf, 14.863733439268286, 0.001); - EXPECT_NEAR(state->dataHeatBalFanSys->ZoneAirHumRatAvgComf(1), 0.010564839505489259, 0.0001); + EXPECT_NEAR(state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvgComf, 0.010564839505489259, 0.0001); EXPECT_NEAR(state->dataThermalComforts->ThermalComfortData(1).FangerPMV, -5.5896341565108720, 0.001); @@ -1958,8 +1959,11 @@ TEST_F(EnergyPlusFixture, ThermalComfort_CalcSurfaceWeightedMRT_Enclosure_Based) state->dataSurface->Surface(11).Zone = 2; state->dataSurface->Surface(12).Zone = 2; - state->dataHeatBal->Zone(1).HTSurfaceFirst = 1; - state->dataHeatBal->Zone(1).HTSurfaceLast = 6; + state->dataHeatBal->Zone(1).spaceIndexes.allocate(1); + state->dataHeatBal->Zone(1).spaceIndexes[0] = 1; + state->dataHeatBal->space.allocate(1); + state->dataHeatBal->space(1).HTSurfaceFirst = 1; + state->dataHeatBal->space(1).HTSurfaceLast = 6; state->dataHeatBalSurf->SurfInsideTempHist(1)(1) = 10.0; state->dataHeatBalSurf->SurfInsideTempHist(1)(2) = 10.0; state->dataHeatBalSurf->SurfInsideTempHist(1)(3) = 10.0; diff --git a/tst/EnergyPlus/unit/UnitaryHybridAirConditioner.unit.cc b/tst/EnergyPlus/unit/UnitaryHybridAirConditioner.unit.cc index 2c990486224..6801a2f3dac 100644 --- a/tst/EnergyPlus/unit/UnitaryHybridAirConditioner.unit.cc +++ b/tst/EnergyPlus/unit/UnitaryHybridAirConditioner.unit.cc @@ -63,7 +63,6 @@ #include #include #include -#include #include #include #include @@ -84,6 +83,7 @@ #include #include #include +#include using namespace EnergyPlus::MixedAir; using namespace EnergyPlus::DataContaminantBalance; @@ -93,7 +93,6 @@ using namespace EnergyPlus::DataSizing; using namespace EnergyPlus::DataHeatBalance; using namespace EnergyPlus::ScheduleManager; using namespace EnergyPlus::DataEnvironment; -using namespace EnergyPlus::DataHeatBalFanSys; using namespace EnergyPlus::DataZoneEquipment; using namespace EnergyPlus::DataLoopNode; using namespace EnergyPlus::DataZoneEnergyDemands; @@ -411,8 +410,7 @@ TEST_F(EnergyPlusFixture, Test_UnitaryHybridAirConditioner_Unittest) DataZoneEquipment::GetZoneEquipmentData(*state); // read zone equipment SystemReports::ReportMaxVentilationLoads(); state->dataZoneEquip->ZoneEquipInputsFilled = true; state->dataHeatBal->ZnAirRpt.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->MAT.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->ZoneAirHumRatAvg.allocate(state->dataGlobal->NumOfZones); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(state->dataGlobal->NumOfZones); SystemReports::AllocateAndSetUpVentReports(*state); state->dataZoneEnergyDemand->ZoneSysEnergyDemand(1).TotalOutputRequired = 58469.99445; state->dataZoneEnergyDemand->DeadBandOrSetback(1) = false; diff --git a/tst/EnergyPlus/unit/UnitarySystem.unit.cc b/tst/EnergyPlus/unit/UnitarySystem.unit.cc index 4f40a2597df..86a83f4d170 100644 --- a/tst/EnergyPlus/unit/UnitarySystem.unit.cc +++ b/tst/EnergyPlus/unit/UnitarySystem.unit.cc @@ -15956,10 +15956,10 @@ TEST_F(EnergyPlusFixture, Test_UnitarySystemModel_SubcoolReheatCoil) state->dataLoopNodes->Node(1).HumRat = 0.01522; // 17C wb state->dataLoopNodes->Node(1).Enthalpy = Psychrometrics::PsyHFnTdbW(state->dataLoopNodes->Node(1).Temp, state->dataLoopNodes->Node(1).HumRat); state->dataLoopNodes->Node(1).Press = state->dataEnvrn->OutBaroPress; - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat(1) = state->dataLoopNodes->Node(1).HumRat; - state->dataHeatBalFanSys->MAT(1) = state->dataLoopNodes->Node(1).Temp; + + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = state->dataLoopNodes->Node(1).HumRat; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = state->dataLoopNodes->Node(1).Temp; state->dataZoneEquip->ZoneEquipList(1).EquipIndex(1) = 1; state->dataZoneEnergyDemand->CurDeadBandOrSetback.allocate(1); @@ -16012,8 +16012,8 @@ TEST_F(EnergyPlusFixture, Test_UnitarySystemModel_SubcoolReheatCoil) state->dataLoopNodes->Node(8).Temp = 24.18496; // 24C db state->dataLoopNodes->Node(8).HumRat = 0.0121542; // 17C wb state->dataLoopNodes->Node(8).Enthalpy = Psychrometrics::PsyHFnTdbW(state->dataLoopNodes->Node(8).Temp, state->dataLoopNodes->Node(8).HumRat); - state->dataHeatBalFanSys->ZoneAirHumRat(1) = state->dataLoopNodes->Node(1).HumRat; - state->dataHeatBalFanSys->MAT(1) = state->dataLoopNodes->Node(1).Temp; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = state->dataLoopNodes->Node(1).HumRat; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = state->dataLoopNodes->Node(1).Temp; state->dataZoneEnergyDemand->ZoneSysEnergyDemand(1).RemainingOutputRequired = -397.162; state->dataZoneEnergyDemand->ZoneSysEnergyDemand(1).RemainingOutputReqToCoolSP = -397.162; @@ -17271,10 +17271,10 @@ TEST_F(ZoneUnitarySysTest, UnitarySystemModel_MultiSpeedDXCoilsDirectSolutionTes state->dataLoopNodes->Node(1).HumRat = 0.01522; // 17C wb state->dataLoopNodes->Node(1).Press = state->dataEnvrn->OutBaroPress; state->dataLoopNodes->Node(1).Enthalpy = Psychrometrics::PsyHFnTdbW(state->dataLoopNodes->Node(1).Temp, state->dataLoopNodes->Node(1).HumRat); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat(1) = state->dataLoopNodes->Node(1).HumRat; - state->dataHeatBalFanSys->MAT(1) = state->dataLoopNodes->Node(1).Temp; + + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = state->dataLoopNodes->Node(1).HumRat; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = state->dataLoopNodes->Node(1).Temp; state->dataZoneEquip->ZoneEquipList(1).EquipIndex(1) = 1; state->dataZoneEnergyDemand->CurDeadBandOrSetback.allocate(1); diff --git a/tst/EnergyPlus/unit/WaterThermalTanks.unit.cc b/tst/EnergyPlus/unit/WaterThermalTanks.unit.cc index 1a0ab6b3790..3d118cd711a 100644 --- a/tst/EnergyPlus/unit/WaterThermalTanks.unit.cc +++ b/tst/EnergyPlus/unit/WaterThermalTanks.unit.cc @@ -57,7 +57,6 @@ #include "Fixtures/EnergyPlusFixture.hh" #include #include -#include #include #include #include @@ -73,6 +72,7 @@ #include #include #include +#include using namespace EnergyPlus; using namespace OutputReportPredefined; @@ -1037,8 +1037,8 @@ TEST_F(EnergyPlusFixture, HPWHSizing) ASSERT_FALSE(ErrorsFound); state->dataHVACGlobal->TimeStepSys = 1; SetPredefinedTables(*state); - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->MAT(1) = 20.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 20.0; WaterThermalTanks::SimHeatPumpWaterHeater(*state, "Zone4HeatPumpWaterHeater", true, SenseLoadMet, LatLoadMet, CompIndex); EXPECT_EQ(state->dataFans->Fan(1).MaxAirFlowRate, state->dataWaterThermalTanks->HPWaterHeater(1).OperatingAirFlowRate); EXPECT_EQ(state->dataFans->Fan(1).MaxAirFlowRate, state->dataDXCoils->DXCoil(1).RatedAirVolFlowRate(1)); diff --git a/tst/EnergyPlus/unit/WindowManager.unit.cc b/tst/EnergyPlus/unit/WindowManager.unit.cc index 3da1d874358..1131569f69a 100644 --- a/tst/EnergyPlus/unit/WindowManager.unit.cc +++ b/tst/EnergyPlus/unit/WindowManager.unit.cc @@ -81,6 +81,7 @@ #include #include #include +#include #include "Fixtures/EnergyPlusFixture.hh" @@ -204,15 +205,13 @@ TEST_F(EnergyPlusFixture, WindowFrameTest) state->dataGlobal->BeginEnvrnFlag = true; state->dataEnvrn->OutBaroPress = 100000; - state->dataHeatBalFanSys->ZTAV.allocate(1); - state->dataHeatBalFanSys->ZT.allocate(1); state->dataHeatBal->ZoneMRT.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRatAvg.allocate(1); - state->dataHeatBalFanSys->ZT(1) = 0.0; - state->dataHeatBalFanSys->ZTAV(1) = 0.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZT = 0.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 0.0; state->dataHeatBal->ZoneMRT(1) = 0.0; - state->dataHeatBalFanSys->ZoneAirHumRatAvg(1) = 0.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvg = 0.0; HeatBalanceManager::ManageHeatBalance(*state); @@ -246,9 +245,10 @@ TEST_F(EnergyPlusFixture, WindowFrameTest) state->dataSurface->SurfOutDryBulbTemp(winNum) = T_out; state->dataHeatBal->SurfTempEffBulkAir(winNum) = T_in; state->dataSurface->SurfWinIRfromParentZone(winNum) = DataGlobalConstants::StefanBoltzmann * std::pow(T_in + DataGlobalConstants::KelvinConv, 4); - state->dataHeatBalFanSys->ZoneAirHumRatAvg.dimension(1, 0.01); - state->dataHeatBalFanSys->ZoneAirHumRat.dimension(1, 0.01); - state->dataHeatBalFanSys->MAT.dimension(1, T_in); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = T_in; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvg = 0.01; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.01; // initial guess temperatures int numTemps = 2 + 2 * state->dataConstruction->Construct(cNum).TotGlassLayers; @@ -540,13 +540,11 @@ TEST_F(EnergyPlusFixture, WindowManager_RefAirTempTest) state->dataHeatBalSurf->SurfHConvInt(surfNum2) = 0.5; state->dataHeatBalSurf->SurfHConvInt(surfNum3) = 0.5; state->dataHeatBal->Zone(1).IsControlled = true; - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.011; - state->dataHeatBalFanSys->ZoneAirHumRatAvg.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRatAvg(1) = state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.011; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 25.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvg = 0.011; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.011; - state->dataHeatBalFanSys->MAT.allocate(1); - state->dataHeatBalFanSys->MAT(1) = 25.0; state->dataHeatBalSurf->SurfQdotRadHVACInPerArea.allocate(3); state->dataHeatBal->SurfWinQRadSWwinAbs.allocate(3, 1); state->dataHeatBal->SurfQdotRadIntGainsInPerArea.allocate(3); @@ -2807,16 +2805,15 @@ TEST_F(EnergyPlusFixture, WindowManager_SrdLWRTest) state->dataHeatBalSurf->SurfHConvInt(surfNum2) = 0.5; state->dataHeatBalSurf->SurfHConvInt(surfNum3) = 0.5; state->dataHeatBal->Zone(1).IsControlled = true; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.011; - state->dataHeatBalFanSys->ZoneAirHumRatAvg(1) = state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.011; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 25.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvg = 0.011; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.011; // initialize simple glazing adjustment ratio state->dataHeatBalSurf->SurfWinCoeffAdjRatio.allocate(3); state->dataHeatBalSurf->SurfWinCoeffAdjRatio(surfNum2) = 1.0024; - state->dataHeatBalFanSys->MAT.allocate(1); - - state->dataHeatBalFanSys->MAT(1) = 25.0; state->dataSurface->SurfTAirRef(surfNum1) = DataSurfaces::RefAirTemp::ZoneMeanAirTemp; state->dataSurface->SurfTAirRef(surfNum2) = DataSurfaces::RefAirTemp::ZoneSupplyAirTemp; state->dataSurface->SurfTAirRef(surfNum3) = DataSurfaces::RefAirTemp::AdjacentAirTemp; @@ -7675,15 +7672,13 @@ TEST_F(EnergyPlusFixture, CFS_InteriorSolarDistribution_Test) state->dataGlobal->BeginEnvrnFlag = true; state->dataEnvrn->OutBaroPress = 101325.0; - state->dataHeatBalFanSys->ZTAV.allocate(1); - state->dataHeatBalFanSys->ZT.allocate(1); state->dataHeatBal->ZoneMRT.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRatAvg.allocate(1); - state->dataHeatBalFanSys->ZT(1) = 0.0; - state->dataHeatBalFanSys->ZTAV(1) = 0.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZT = 0.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZTAV = 0.0; state->dataHeatBal->ZoneMRT(1) = 0.0; - state->dataHeatBalFanSys->ZoneAirHumRatAvg(1) = 0.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvg = 0.0; HeatBalanceManager::ManageHeatBalance(*state); @@ -7705,9 +7700,10 @@ TEST_F(EnergyPlusFixture, CFS_InteriorSolarDistribution_Test) DataGlobalConstants::StefanBoltzmann * std::pow(T_in + DataGlobalConstants::KelvinConv, 4); } } - state->dataHeatBalFanSys->ZoneAirHumRatAvg.dimension(1, 0.01); - state->dataHeatBalFanSys->ZoneAirHumRat.dimension(1, 0.01); - state->dataHeatBalFanSys->MAT.dimension(1, T_in); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRatAvg = 0.01; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.01; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = T_in; state->dataEnvrn->BeamSolarRad = I_s; if (I_s > 0.0) { diff --git a/tst/EnergyPlus/unit/ZoneContaminantPredictorCorrector.unit.cc b/tst/EnergyPlus/unit/ZoneContaminantPredictorCorrector.unit.cc index 315de1a344f..63314d01ebe 100644 --- a/tst/EnergyPlus/unit/ZoneContaminantPredictorCorrector.unit.cc +++ b/tst/EnergyPlus/unit/ZoneContaminantPredictorCorrector.unit.cc @@ -76,7 +76,6 @@ using namespace EnergyPlus; using namespace EnergyPlus::DataHeatBalance; -using namespace EnergyPlus::DataHeatBalFanSys; using namespace DataStringGlobals; using namespace EnergyPlus::DataZoneControls; using namespace EnergyPlus::DataZoneEquipment; @@ -100,9 +99,7 @@ TEST_F(EnergyPlusFixture, ZoneContaminantPredictorCorrector_AddMDotOATest) state->dataHVACGlobal->ShortenTimeStepSys = false; state->dataHVACGlobal->UseZoneTimeStepHistory = false; - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); - state->dataHeatBalFanSys->ZT.allocate(1); - state->dataHeatBalFanSys->MixingMassFlowZone.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); state->dataGlobal->NumOfZones = 1; state->dataContaminantBalance->Contaminant.CO2Simulation = true; @@ -196,19 +193,11 @@ TEST_F(EnergyPlusFixture, ZoneContaminantPredictorCorrector_AddMDotOATest) state->dataHeatBal->Zone(1).ZoneVolCapMultpMoist = 1.0; state->dataEnvrn->OutBaroPress = 101325.0; - state->dataHybridModel->HybridModelZone.allocate(1); - state->dataHybridModel->HybridModelZone(1).InfiltrationCalc_C = false; - state->dataHybridModel->HybridModelZone(1).PeopleCountCalc_C = false; - state->dataZonePlenum->NumZoneReturnPlenums = 0; state->dataZonePlenum->NumZoneSupplyPlenums = 0; - state->dataHeatBalFanSys->OAMFL.allocate(1); - state->dataHeatBalFanSys->VAMFL.allocate(1); - state->dataHeatBalFanSys->EAMFL.allocate(1); - state->dataHeatBalFanSys->CTMFL.allocate(1); - state->dataHeatBalFanSys->MDotOA.allocate(1); - state->dataHeatBalFanSys->MDotOA(1) = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MDotOA = 0.001; state->dataScheduleMgr->Schedule.allocate(1); state->dataScheduleMgr->Schedule(1).CurrentValue = 1.0; @@ -226,13 +215,9 @@ TEST_F(EnergyPlusFixture, ZoneContaminantPredictorCorrector_AddMDotOATest) state->dataLoopNodes->Node(4).MassFlowRate = 0.03; // Zone return node state->dataLoopNodes->Node(4).HumRat = 0.000; state->dataLoopNodes->Node(5).HumRat = 0.000; - state->dataHeatBalFanSys->OAMFL(1) = 0.0; - state->dataHeatBalFanSys->VAMFL(1) = 0.0; - state->dataHeatBalFanSys->EAMFL(1) = 0.0; - state->dataHeatBalFanSys->CTMFL(1) = 0.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.008; - state->dataHeatBalFanSys->ZT(1) = 24.0; - state->dataHeatBalFanSys->MixingMassFlowZone(1) = 0.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.008; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZT = 24.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MixingMassFlowZone = 0.0; state->dataContaminantBalance->CO2PredictedRate.allocate(1); state->dataContaminantBalance->ZoneSysContDemand.allocate(1); @@ -259,9 +244,7 @@ TEST_F(EnergyPlusFixture, ZoneContaminantPredictorCorrector_CorrectZoneContamina state->dataHVACGlobal->ShortenTimeStepSys = false; state->dataHVACGlobal->UseZoneTimeStepHistory = false; - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); - state->dataHeatBalFanSys->ZT.allocate(1); - state->dataHeatBalFanSys->MixingMassFlowZone.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); state->dataGlobal->NumOfZones = 1; state->dataContaminantBalance->Contaminant.CO2Simulation = true; @@ -342,19 +325,10 @@ TEST_F(EnergyPlusFixture, ZoneContaminantPredictorCorrector_CorrectZoneContamina state->dataHeatBal->Zone(1).ZoneVolCapMultpMoist = 1.0; state->dataEnvrn->OutBaroPress = 101325.0; - state->dataHybridModel->HybridModelZone.allocate(1); - state->dataHybridModel->HybridModelZone(1).InfiltrationCalc_C = false; - state->dataHybridModel->HybridModelZone(1).PeopleCountCalc_C = false; - state->dataZonePlenum->NumZoneReturnPlenums = 0; state->dataZonePlenum->NumZoneSupplyPlenums = 0; - state->dataHeatBalFanSys->OAMFL.allocate(1); - state->dataHeatBalFanSys->VAMFL.allocate(1); - state->dataHeatBalFanSys->EAMFL.allocate(1); - state->dataHeatBalFanSys->CTMFL.allocate(1); - state->dataHeatBalFanSys->MDotOA.allocate(1); - state->dataHeatBalFanSys->MDotOA(1) = 0.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); state->dataHeatBal->ZoneAirSolutionAlgo = DataHeatBalance::SolutionAlgo::EulerMethod; @@ -369,13 +343,9 @@ TEST_F(EnergyPlusFixture, ZoneContaminantPredictorCorrector_CorrectZoneContamina state->dataLoopNodes->Node(4).MassFlowRate = 0.03; // Zone return node state->dataLoopNodes->Node(4).HumRat = 0.000; state->dataLoopNodes->Node(5).HumRat = 0.000; - state->dataHeatBalFanSys->OAMFL(1) = 0.0; - state->dataHeatBalFanSys->VAMFL(1) = 0.0; - state->dataHeatBalFanSys->EAMFL(1) = 0.0; - state->dataHeatBalFanSys->CTMFL(1) = 0.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.008; - state->dataHeatBalFanSys->ZT(1) = 24.0; - state->dataHeatBalFanSys->MixingMassFlowZone(1) = 0.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.008; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZT = 24.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MixingMassFlowZone = 0.0; CorrectZoneContaminants(*state, state->dataHVACGlobal->UseZoneTimeStepHistory); EXPECT_NEAR(490.0, state->dataLoopNodes->Node(5).CO2, 0.00001); @@ -388,9 +358,7 @@ TEST_F(EnergyPlusFixture, ZoneContaminantPredictorCorrector_MultiZoneCO2ControlT state->dataHVACGlobal->ShortenTimeStepSys = false; state->dataHVACGlobal->UseZoneTimeStepHistory = false; - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(3); - state->dataHeatBalFanSys->ZT.allocate(3); - state->dataHeatBalFanSys->MixingMassFlowZone.allocate(3); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(3); state->dataGlobal->NumOfZones = 3; @@ -522,12 +490,10 @@ TEST_F(EnergyPlusFixture, ZoneContaminantPredictorCorrector_MultiZoneCO2ControlT state->dataZonePlenum->NumZoneReturnPlenums = 0; state->dataZonePlenum->NumZoneSupplyPlenums = 0; - state->dataHeatBalFanSys->OAMFL.allocate(3); - state->dataHeatBalFanSys->VAMFL.allocate(3); - state->dataHeatBalFanSys->EAMFL.allocate(3); - state->dataHeatBalFanSys->CTMFL.allocate(3); - state->dataHeatBalFanSys->MDotOA.allocate(3); - state->dataHeatBalFanSys->MDotOA = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(3); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MDotOA = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MDotOA = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(3).MDotOA = 0.001; state->dataScheduleMgr->Schedule.allocate(1); state->dataScheduleMgr->Schedule(1).CurrentValue = 1.0; @@ -545,25 +511,15 @@ TEST_F(EnergyPlusFixture, ZoneContaminantPredictorCorrector_MultiZoneCO2ControlT state->dataLoopNodes->Node(4).MassFlowRate = 0.03; // Zone return node state->dataLoopNodes->Node(4).HumRat = 0.000; state->dataLoopNodes->Node(5).HumRat = 0.000; - state->dataHeatBalFanSys->OAMFL(1) = 0.0; - state->dataHeatBalFanSys->VAMFL(1) = 0.0; - state->dataHeatBalFanSys->EAMFL(1) = 0.0; - state->dataHeatBalFanSys->CTMFL(1) = 0.0; - state->dataHeatBalFanSys->OAMFL(2) = 0.0; - state->dataHeatBalFanSys->VAMFL(2) = 0.0; - state->dataHeatBalFanSys->EAMFL(2) = 0.0; - state->dataHeatBalFanSys->CTMFL(2) = 0.0; - state->dataHeatBalFanSys->OAMFL(3) = 0.0; - state->dataHeatBalFanSys->VAMFL(3) = 0.0; - state->dataHeatBalFanSys->EAMFL(3) = 0.0; - state->dataHeatBalFanSys->CTMFL(3) = 0.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.008; - state->dataHeatBalFanSys->ZT(1) = 24.0; - state->dataHeatBalFanSys->ZoneAirHumRat(2) = 0.008; - state->dataHeatBalFanSys->ZT(2) = 23.5; - state->dataHeatBalFanSys->ZoneAirHumRat(3) = 0.008; - state->dataHeatBalFanSys->ZT(3) = 24.5; - state->dataHeatBalFanSys->MixingMassFlowZone = 0.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.008; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZT = 24.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).ZoneAirHumRat = 0.008; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).ZT = 23.5; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(3).ZoneAirHumRat = 0.008; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(3).ZT = 24.5; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MixingMassFlowZone = 0.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MixingMassFlowZone = 0.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(3).MixingMassFlowZone = 0.0; state->dataLoopNodes->Node(6).MassFlowRate = 0.01; state->dataLoopNodes->Node(7).MassFlowRate = 0.01; @@ -597,9 +553,7 @@ TEST_F(EnergyPlusFixture, ZoneContaminantPredictorCorrector_MultiZoneGCControlTe state->dataHVACGlobal->ShortenTimeStepSys = false; state->dataHVACGlobal->UseZoneTimeStepHistory = false; - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(3); - state->dataHeatBalFanSys->ZT.allocate(3); - state->dataHeatBalFanSys->MixingMassFlowZone.allocate(3); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(3); state->dataGlobal->NumOfZones = 3; @@ -721,12 +675,10 @@ TEST_F(EnergyPlusFixture, ZoneContaminantPredictorCorrector_MultiZoneGCControlTe state->dataZonePlenum->NumZoneReturnPlenums = 0; state->dataZonePlenum->NumZoneSupplyPlenums = 0; - state->dataHeatBalFanSys->OAMFL.allocate(3); - state->dataHeatBalFanSys->VAMFL.allocate(3); - state->dataHeatBalFanSys->EAMFL.allocate(3); - state->dataHeatBalFanSys->CTMFL.allocate(3); - state->dataHeatBalFanSys->MDotOA.allocate(3); - state->dataHeatBalFanSys->MDotOA = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(3); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MDotOA = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MDotOA = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(3).MDotOA = 0.001; state->dataScheduleMgr->Schedule.allocate(1); state->dataScheduleMgr->Schedule(1).CurrentValue = 1.0; @@ -744,25 +696,15 @@ TEST_F(EnergyPlusFixture, ZoneContaminantPredictorCorrector_MultiZoneGCControlTe state->dataLoopNodes->Node(4).MassFlowRate = 0.03; // Zone return node state->dataLoopNodes->Node(4).HumRat = 0.000; state->dataLoopNodes->Node(5).HumRat = 0.000; - state->dataHeatBalFanSys->OAMFL(1) = 0.0; - state->dataHeatBalFanSys->VAMFL(1) = 0.0; - state->dataHeatBalFanSys->EAMFL(1) = 0.0; - state->dataHeatBalFanSys->CTMFL(1) = 0.0; - state->dataHeatBalFanSys->OAMFL(2) = 0.0; - state->dataHeatBalFanSys->VAMFL(2) = 0.0; - state->dataHeatBalFanSys->EAMFL(2) = 0.0; - state->dataHeatBalFanSys->CTMFL(2) = 0.0; - state->dataHeatBalFanSys->OAMFL(3) = 0.0; - state->dataHeatBalFanSys->VAMFL(3) = 0.0; - state->dataHeatBalFanSys->EAMFL(3) = 0.0; - state->dataHeatBalFanSys->CTMFL(3) = 0.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.008; - state->dataHeatBalFanSys->ZT(1) = 24.0; - state->dataHeatBalFanSys->ZoneAirHumRat(2) = 0.008; - state->dataHeatBalFanSys->ZT(2) = 23.5; - state->dataHeatBalFanSys->ZoneAirHumRat(3) = 0.008; - state->dataHeatBalFanSys->ZT(3) = 24.5; - state->dataHeatBalFanSys->MixingMassFlowZone = 0.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.008; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZT = 24.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).ZoneAirHumRat = 0.008; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).ZT = 23.5; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(3).ZoneAirHumRat = 0.008; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(3).ZT = 24.5; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MixingMassFlowZone = 0.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MixingMassFlowZone = 0.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(3).MixingMassFlowZone = 0.0; state->dataLoopNodes->Node(6).MassFlowRate = 0.01; diff --git a/tst/EnergyPlus/unit/ZoneEquipmentManager.unit.cc b/tst/EnergyPlus/unit/ZoneEquipmentManager.unit.cc index 5c9c363635f..737d263b9cf 100644 --- a/tst/EnergyPlus/unit/ZoneEquipmentManager.unit.cc +++ b/tst/EnergyPlus/unit/ZoneEquipmentManager.unit.cc @@ -74,6 +74,7 @@ #include #include #include +#include #include "Fixtures/EnergyPlusFixture.hh" @@ -392,28 +393,18 @@ TEST_F(EnergyPlusFixture, ZoneEquipmentManager_MultiCrossMixingTest) EXPECT_FALSE(ErrorsFound); - state->dataHeatBalFanSys->MAT.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->MCPM.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->MCPTM.allocate(state->dataGlobal->NumOfZones); - - state->dataHeatBalFanSys->MCPI.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->OAMFL.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->MCPTI.allocate(state->dataGlobal->NumOfZones); - - state->dataHeatBalFanSys->MixingMassFlowZone.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->MixingMassFlowXHumRat.allocate(state->dataGlobal->NumOfZones); - - state->dataHeatBalFanSys->MAT(1) = 21.0; - state->dataHeatBalFanSys->MAT(2) = 22.0; - state->dataHeatBalFanSys->MAT(3) = 23.0; - state->dataHeatBalFanSys->MAT(4) = 24.0; - state->dataHeatBalFanSys->MAT(5) = 25.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.001; - state->dataHeatBalFanSys->ZoneAirHumRat(2) = 0.001; - state->dataHeatBalFanSys->ZoneAirHumRat(3) = 0.001; - state->dataHeatBalFanSys->ZoneAirHumRat(4) = 0.001; - state->dataHeatBalFanSys->ZoneAirHumRat(5) = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(state->dataGlobal->NumOfZones); + + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 21.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MAT = 22.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(3).MAT = 23.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(4).MAT = 24.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(5).MAT = 25.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).ZoneAirHumRat = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(3).ZoneAirHumRat = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(4).ZoneAirHumRat = 0.001; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(5).ZoneAirHumRat = 0.001; state->dataHeatBal->AirFlowFlag = true; state->dataScheduleMgr->Schedule(ScheduleManager::GetScheduleIndex(*state, "MIXINGAVAILSCHED")).CurrentValue = 1.0; @@ -428,35 +419,22 @@ TEST_F(EnergyPlusFixture, ZoneEquipmentManager_MultiCrossMixingTest) CalcAirFlowSimple(*state, 2); - EXPECT_NEAR(720.738493, state->dataHeatBalFanSys->MCPM(1), 0.00001); - EXPECT_NEAR(119.818784, state->dataHeatBalFanSys->MCPM(2), 0.00001); - EXPECT_NEAR(599.907893, state->dataHeatBalFanSys->MCPM(3), 0.00001); - EXPECT_NEAR(719.116710, state->dataHeatBalFanSys->MCPM(4), 0.00001); - EXPECT_NEAR(16937.0496, state->dataHeatBalFanSys->MCPTM(1), 0.001); - EXPECT_NEAR(2875.6508, state->dataHeatBalFanSys->MCPTM(2), 0.001); - EXPECT_NEAR(13315.7667, state->dataHeatBalFanSys->MCPTM(3), 0.001); - EXPECT_NEAR(15699.7370, state->dataHeatBalFanSys->MCPTM(4), 0.001); - EXPECT_NEAR(0.71594243, state->dataHeatBalFanSys->MixingMassFlowZone(1), 0.00001); - EXPECT_NEAR(0.11902146, state->dataHeatBalFanSys->MixingMassFlowZone(2), 0.00001); - EXPECT_NEAR(0.59591588, state->dataHeatBalFanSys->MixingMassFlowZone(3), 0.00001); - EXPECT_NEAR(0.71433143, state->dataHeatBalFanSys->MixingMassFlowZone(4), 0.00001); - EXPECT_NEAR(0.00071594243, state->dataHeatBalFanSys->MixingMassFlowXHumRat(1), 0.0000001); - EXPECT_NEAR(0.00011902146, state->dataHeatBalFanSys->MixingMassFlowXHumRat(2), 0.0000001); - EXPECT_NEAR(0.00059591588, state->dataHeatBalFanSys->MixingMassFlowXHumRat(3), 0.0000001); - EXPECT_NEAR(0.00071433143, state->dataHeatBalFanSys->MixingMassFlowXHumRat(4), 0.0000001); - - // Deallocate everything - should all be taken care of in clear_states - - state->dataHeatBalFanSys->MAT.deallocate(); - state->dataHeatBalFanSys->ZoneAirHumRat.deallocate(); - state->dataHeatBalFanSys->MCPM.deallocate(); - state->dataHeatBalFanSys->MCPTM.deallocate(); - state->dataHeatBalFanSys->MCPI.deallocate(); - state->dataHeatBalFanSys->OAMFL.deallocate(); - state->dataHeatBalFanSys->MCPTI.deallocate(); - state->dataHeatBalFanSys->MixingMassFlowZone.deallocate(); - state->dataHeatBalFanSys->MixingMassFlowXHumRat.deallocate(); - state->dataHeatBalFanSys->ZoneReOrder.deallocate(); + EXPECT_NEAR(720.738493, state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MCPM, 0.00001); + EXPECT_NEAR(119.818784, state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MCPM, 0.00001); + EXPECT_NEAR(599.907893, state->dataZoneTempPredictorCorrector->zoneHeatBalance(3).MCPM, 0.00001); + EXPECT_NEAR(719.116710, state->dataZoneTempPredictorCorrector->zoneHeatBalance(4).MCPM, 0.00001); + EXPECT_NEAR(16937.0496, state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MCPTM, 0.001); + EXPECT_NEAR(2875.6508, state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MCPTM, 0.001); + EXPECT_NEAR(13315.7667, state->dataZoneTempPredictorCorrector->zoneHeatBalance(3).MCPTM, 0.001); + EXPECT_NEAR(15699.7370, state->dataZoneTempPredictorCorrector->zoneHeatBalance(4).MCPTM, 0.001); + EXPECT_NEAR(0.71594243, state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MixingMassFlowZone, 0.00001); + EXPECT_NEAR(0.11902146, state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MixingMassFlowZone, 0.00001); + EXPECT_NEAR(0.59591588, state->dataZoneTempPredictorCorrector->zoneHeatBalance(3).MixingMassFlowZone, 0.00001); + EXPECT_NEAR(0.71433143, state->dataZoneTempPredictorCorrector->zoneHeatBalance(4).MixingMassFlowZone, 0.00001); + EXPECT_NEAR(0.00071594243, state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MixingMassFlowXHumRat, 0.0000001); + EXPECT_NEAR(0.00011902146, state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MixingMassFlowXHumRat, 0.0000001); + EXPECT_NEAR(0.00059591588, state->dataZoneTempPredictorCorrector->zoneHeatBalance(3).MixingMassFlowXHumRat, 0.0000001); + EXPECT_NEAR(0.00071433143, state->dataZoneTempPredictorCorrector->zoneHeatBalance(4).MixingMassFlowXHumRat, 0.0000001); } TEST_F(EnergyPlusFixture, ZoneEquipmentManager_CalcZoneMassBalanceTest2) @@ -3375,7 +3353,7 @@ TEST_F(EnergyPlusFixture, ZoneAirMassFlowBalance_wAdjustReturnOnly) EXPECT_EQ(state->dataHeatBal->MassConservation(2).MixingSourceMassFlowRate, 0.0); EXPECT_NEAR(state->dataHeatBal->MassConservation(2).MixingMassFlowRate, 0.586632, 0.000001); // zone mixing object is defined in the receiving zone and the flow is not adjusted - EXPECT_NEAR(state->dataHeatBalFanSys->MixingMassFlowZone(2), 0.586632, 0.000001); + EXPECT_NEAR(state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MixingMassFlowZone, 0.586632, 0.000001); EXPECT_EQ(state->dataHeatBal->MassConservation(2).InfiltrationMassFlowRate, 0.0); ; ; @@ -3401,7 +3379,7 @@ TEST_F(EnergyPlusFixture, ZoneAirMassFlowBalance_wAdjustReturnOnly) EXPECT_EQ(state->dataHeatBal->MassConservation(2).MixingSourceMassFlowRate, 0.0); EXPECT_NEAR(state->dataHeatBal->MassConservation(2).MixingMassFlowRate, 0.586632, 0.000001); // zone mixing object is defined in the receiving zone and the flow is not adjusted - EXPECT_NEAR(state->dataHeatBalFanSys->MixingMassFlowZone(2), 0.586632, 0.000001); + EXPECT_NEAR(state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MixingMassFlowZone, 0.586632, 0.000001); EXPECT_NEAR(state->dataHeatBal->MassConservation(2).InfiltrationMassFlowRate, 0.413368, 0.000001); ; ; @@ -3430,7 +3408,7 @@ TEST_F(EnergyPlusFixture, ZoneAirMassFlowBalance_wAdjustReturnOnly) EXPECT_EQ(state->dataHeatBal->MassConservation(2).MixingSourceMassFlowRate, 0.0); EXPECT_NEAR(state->dataHeatBal->MassConservation(2).MixingMassFlowRate, 1.173265, 0.000001); // zone mixing object is defined in the receiving zone and the flow is not adjusted - EXPECT_NEAR(state->dataHeatBalFanSys->MixingMassFlowZone(2), 1.173265, 0.000001); + EXPECT_NEAR(state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MixingMassFlowZone, 1.173265, 0.000001); EXPECT_NEAR(state->dataHeatBal->MassConservation(2).InfiltrationMassFlowRate, 0.826735, 0.000001); } @@ -3640,7 +3618,7 @@ TEST_F(EnergyPlusFixture, ZoneAirMassFlowBalance_wAdjustReturnThenMixing) EXPECT_EQ(state->dataHeatBal->MassConservation(2).MixingSourceMassFlowRate, 0.0); EXPECT_NEAR(state->dataHeatBal->MassConservation(2).MixingMassFlowRate, 0.586632, 0.000001); // zone mixing object is defined in the receiving zone and the flow is not adjusted - EXPECT_NEAR(state->dataHeatBalFanSys->MixingMassFlowZone(2), 0.586632, 0.000001); + EXPECT_NEAR(state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MixingMassFlowZone, 0.586632, 0.000001); EXPECT_EQ(state->dataHeatBal->MassConservation(2).InfiltrationMassFlowRate, 0.0); ; ; @@ -3667,7 +3645,7 @@ TEST_F(EnergyPlusFixture, ZoneAirMassFlowBalance_wAdjustReturnThenMixing) EXPECT_EQ(state->dataHeatBal->MassConservation(2).MixingSourceMassFlowRate, 0.0); EXPECT_NEAR(state->dataHeatBal->MassConservation(2).MixingMassFlowRate, 1.0, 0.000001); // zone mixing object flow is modified - EXPECT_NEAR(state->dataHeatBalFanSys->MixingMassFlowZone(2), 1.0, 0.000001); + EXPECT_NEAR(state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MixingMassFlowZone, 1.0, 0.000001); EXPECT_EQ(state->dataHeatBal->MassConservation(2).InfiltrationMassFlowRate, 0.0); ; ; @@ -3697,7 +3675,7 @@ TEST_F(EnergyPlusFixture, ZoneAirMassFlowBalance_wAdjustReturnThenMixing) EXPECT_EQ(state->dataHeatBal->MassConservation(2).MixingSourceMassFlowRate, 0.0); EXPECT_NEAR(state->dataHeatBal->MassConservation(2).MixingMassFlowRate, 2.0, 0.000001); // zone mixing object flow is modified - EXPECT_NEAR(state->dataHeatBalFanSys->MixingMassFlowZone(2), 2.0, 0.000001); + EXPECT_NEAR(state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MixingMassFlowZone, 2.0, 0.000001); EXPECT_EQ(state->dataHeatBal->MassConservation(2).InfiltrationMassFlowRate, 0.0); } @@ -3908,7 +3886,7 @@ TEST_F(EnergyPlusFixture, ZoneAirMassFlowBalance_wAdjustMixingThenReturn) EXPECT_EQ(state->dataHeatBal->MassConservation(2).MixingSourceMassFlowRate, 0.0); EXPECT_NEAR(state->dataHeatBal->MassConservation(2).MixingMassFlowRate, 0.586632, 0.000001); // zone mixing object is defined in the receiving zone and the flow is not adjusted - EXPECT_NEAR(state->dataHeatBalFanSys->MixingMassFlowZone(2), 0.586632, 0.000001); + EXPECT_NEAR(state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MixingMassFlowZone, 0.586632, 0.000001); EXPECT_EQ(state->dataHeatBal->MassConservation(2).InfiltrationMassFlowRate, 0.0); ; ; @@ -3935,7 +3913,7 @@ TEST_F(EnergyPlusFixture, ZoneAirMassFlowBalance_wAdjustMixingThenReturn) EXPECT_EQ(state->dataHeatBal->MassConservation(2).MixingSourceMassFlowRate, 0.0); EXPECT_NEAR(state->dataHeatBal->MassConservation(2).MixingMassFlowRate, 1.0, 0.000001); // zone mixing object flow is modified - EXPECT_NEAR(state->dataHeatBalFanSys->MixingMassFlowZone(2), 1.0, 0.000001); + EXPECT_NEAR(state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MixingMassFlowZone, 1.0, 0.000001); EXPECT_EQ(state->dataHeatBal->MassConservation(2).InfiltrationMassFlowRate, 0.0); // Test 3: set receiving zone exhaust fan flow 3 times supply flow rate @@ -3964,7 +3942,7 @@ TEST_F(EnergyPlusFixture, ZoneAirMassFlowBalance_wAdjustMixingThenReturn) EXPECT_EQ(state->dataHeatBal->MassConservation(2).MixingSourceMassFlowRate, 0.0); EXPECT_NEAR(state->dataHeatBal->MassConservation(2).MixingMassFlowRate, 2.0, 0.000001); // zone mixing object flow is modified - EXPECT_NEAR(state->dataHeatBalFanSys->MixingMassFlowZone(2), 2.0, 0.000001); + EXPECT_NEAR(state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MixingMassFlowZone, 2.0, 0.000001); EXPECT_EQ(state->dataHeatBal->MassConservation(2).InfiltrationMassFlowRate, 0.0); } @@ -4222,7 +4200,7 @@ TEST_F(EnergyPlusFixture, ZoneAirMassFlowBalance_wSourceAndReceivingZone) EXPECT_NEAR(state->dataHeatBal->MassConservation(2).MixingSourceMassFlowRate, 1.0, 0.000001); EXPECT_NEAR(state->dataHeatBal->MassConservation(2).MixingMassFlowRate, 1.0, 0.000001); // zone mixing object is defined in the receiving zone and the flow is not adjusted - EXPECT_NEAR(state->dataHeatBalFanSys->MixingMassFlowZone(2), 1.0, 0.000001); + EXPECT_NEAR(state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MixingMassFlowZone, 1.0, 0.000001); EXPECT_EQ(state->dataHeatBal->MassConservation(2).InfiltrationMassFlowRate, 0.0); EXPECT_TRUE(state->dataHeatBal->MassConservation(2).IsSourceAndReceivingZone); // zone 2, receiving only zone mass conservation results @@ -4232,7 +4210,7 @@ TEST_F(EnergyPlusFixture, ZoneAirMassFlowBalance_wSourceAndReceivingZone) EXPECT_NEAR(state->dataHeatBal->MassConservation(3).MixingSourceMassFlowRate, 0.0, 0.000001); EXPECT_NEAR(state->dataHeatBal->MassConservation(3).MixingMassFlowRate, 1.0, 0.000001); // zone mixing object is defined in the receiving zone and the flow is not adjusted - EXPECT_NEAR(state->dataHeatBalFanSys->MixingMassFlowZone(3), 1.0, 0.000001); + EXPECT_NEAR(state->dataZoneTempPredictorCorrector->zoneHeatBalance(3).MixingMassFlowZone, 1.0, 0.000001); EXPECT_EQ(state->dataHeatBal->MassConservation(3).InfiltrationMassFlowRate, 0.0); EXPECT_FALSE(state->dataHeatBal->MassConservation(3).IsOnlySourceZone); EXPECT_FALSE(state->dataHeatBal->MassConservation(3).IsSourceAndReceivingZone); @@ -4419,25 +4397,12 @@ TEST_F(EnergyPlusFixture, CalcAirFlowSimple_CO2andGCforRefrigerationDoorsTest) state->dataEnvrn->OutBaroPress = 101400.; - state->dataHeatBalFanSys->MAT.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->MCPM.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->MCPTM.allocate(state->dataGlobal->NumOfZones); - - state->dataHeatBalFanSys->MCPI.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->OAMFL.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->MCPTI.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->MCPThermChim.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->ThermChimAMFL.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->MCPTThermChim.allocate(state->dataGlobal->NumOfZones); - - state->dataHeatBalFanSys->MixingMassFlowZone.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->MixingMassFlowXHumRat.allocate(state->dataGlobal->NumOfZones); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->MAT(1) = 21.0; - state->dataHeatBalFanSys->MAT(2) = 22.0; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.0021; - state->dataHeatBalFanSys->ZoneAirHumRat(2) = 0.0022; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).MAT = 21.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).MAT = 22.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(1).ZoneAirHumRat = 0.0021; + state->dataZoneTempPredictorCorrector->zoneHeatBalance(2).ZoneAirHumRat = 0.0022; state->dataHeatBal->TotRefDoorMixing = 1; state->dataHeatBal->TotMixing = 0; @@ -4546,6 +4511,7 @@ TEST_F(EnergyPlusFixture, CZoeEquipmentManager_CalcZoneLeavingConditions_Test) state->dataZoneEnergyDemand->CurDeadBandOrSetback.allocate(1); state->dataZoneEnergyDemand->DeadBandOrSetback.allocate(1); state->dataZoneEquip->ZoneEquipList.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); CalcZoneLeavingConditions(*state, true); // Zone node temperature is the same as input @@ -4570,9 +4536,7 @@ TEST_F(EnergyPlusFixture, ZoneEquipmentManager_SizeZoneEquipment_NoLoadTest) state->dataSize->CalcZoneSizing.allocate(1, state->dataGlobal->NumOfZones); state->dataSize->CalcFinalZoneSizing.allocate(state->dataGlobal->NumOfZones); state->dataSize->FinalZoneSizing.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->ZoneLatentGain.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->NonAirSystemResponse.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBalFanSys->SysDepZoneLoads.allocate(state->dataGlobal->NumOfZones); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(state->dataGlobal->NumOfZones); state->dataZoneEquip->ZoneEquipConfig.allocate(state->dataGlobal->NumOfZones); state->dataHeatBalFanSys->TempControlType.allocate(state->dataGlobal->NumOfZones); state->dataHeatBalFanSys->TempZoneThermostatSetPoint.allocate(state->dataGlobal->NumOfZones); diff --git a/tst/EnergyPlus/unit/ZoneTempPredictorCorrector.unit.cc b/tst/EnergyPlus/unit/ZoneTempPredictorCorrector.unit.cc index f54ffb9af47..3382b69f046 100644 --- a/tst/EnergyPlus/unit/ZoneTempPredictorCorrector.unit.cc +++ b/tst/EnergyPlus/unit/ZoneTempPredictorCorrector.unit.cc @@ -121,7 +121,6 @@ TEST_F(EnergyPlusFixture, ZoneTempPredictorCorrector_CorrectZoneHumRatTest) state->dataLoopNodes->Node.allocate(5); state->dataHeatBal->Zone.allocate(1); - state->dataHybridModel->HybridModelZone.allocate(1); state->dataHeatBal->Zone(1).Name = state->dataZoneEquip->ZoneEquipConfig(1).ZoneName; state->dataSize->ZoneEqSizing.allocate(1); state->dataSize->CurZoneEqNum = 1; @@ -129,45 +128,33 @@ TEST_F(EnergyPlusFixture, ZoneTempPredictorCorrector_CorrectZoneHumRatTest) state->dataHeatBal->Zone(1).Volume = 1000.0; state->dataHeatBal->Zone(1).SystemZoneNodeNumber = 5; state->dataHeatBal->Zone(1).ZoneVolCapMultpMoist = 1.0; - state->dataHeatBalFanSys->ZoneLatentGain.allocate(1); - state->dataHeatBalFanSys->ZoneLatentGain(1) = 0.0; state->dataHeatBalFanSys->SumLatentHTRadSys.allocate(1); state->dataHeatBalFanSys->SumLatentHTRadSys(1) = 0.0; state->dataHeatBalFanSys->SumLatentPool.allocate(1); state->dataHeatBalFanSys->SumLatentPool(1) = 0.0; state->dataEnvrn->OutBaroPress = 101325.0; - state->dataHeatBalFanSys->ZT.allocate(1); // Zone temperature C - state->dataHeatBalFanSys->ZT(1) = 24.0; - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); - - state->dataHeatBal->Zone(1).HTSurfaceFirst = 1; - state->dataHeatBal->Zone(1).HTSurfaceLast = 2; + state->dataZoneTempPredictorCorrector->spaceHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + auto &thisZoneHB = state->dataZoneTempPredictorCorrector->zoneHeatBalance(1); + thisZoneHB.ZT = 24.0; + + state->dataHeatBal->space.allocate(1); + state->dataHeatBal->spaceIntGainDevices.allocate(1); + state->dataHeatBal->Zone(1).spaceIndexes.emplace_back(1); + state->dataHeatBal->space(1).HTSurfaceFirst = 1; + state->dataHeatBal->space(1).HTSurfaceLast = 2; state->dataSurface->Surface.allocate(2); state->dataZonePlenum->NumZoneReturnPlenums = 0; state->dataZonePlenum->NumZoneSupplyPlenums = 0; - state->dataHeatBalFanSys->OAMFL.allocate(1); - state->dataHeatBalFanSys->VAMFL.allocate(1); - state->dataHeatBalFanSys->EAMFL.allocate(1); - state->dataHeatBalFanSys->EAMFLxHumRat.allocate(1); - state->dataHeatBalFanSys->CTMFL.allocate(1); - - state->dataHeatBalFanSys->SumHmARaW.dimension(1, 0.0); - state->dataHeatBalFanSys->SumHmARa.dimension(1, 0.0); - state->dataHeatBalFanSys->MixingMassFlowXHumRat.allocate(1); - state->dataHeatBalFanSys->MixingMassFlowZone.allocate(1); - state->dataHeatBalFanSys->MDotOA.allocate(1); - state->dataHeatBal->ZoneAirSolutionAlgo = DataHeatBalance::SolutionAlgo::EulerMethod; - state->dataHeatBalFanSys->ZoneAirHumRatTemp.allocate(1); - state->dataHeatBalFanSys->ZoneW1.allocate(1); state->dataRoomAirMod->AirModel.allocate(1); state->dataHeatBal->ZoneIntGain.allocate(1); // Case 1 - All flows at the same humrat - state->dataHeatBalFanSys->ZoneW1(1) = 0.008; + thisZoneHB.ZoneW1 = 0.008; state->dataLoopNodes->Node(1).MassFlowRate = 0.01; // Zone inlet node 1 state->dataLoopNodes->Node(1).HumRat = 0.008; state->dataLoopNodes->Node(2).MassFlowRate = 0.02; // Zone inlet node 2 @@ -175,29 +162,26 @@ TEST_F(EnergyPlusFixture, ZoneTempPredictorCorrector_CorrectZoneHumRatTest) state->dataZoneEquip->ZoneEquipConfig(1).ZoneExhBalanced = 0.0; state->dataLoopNodes->Node(3).MassFlowRate = 0.00; // Zone exhaust node 1 state->dataZoneEquip->ZoneEquipConfig(1).ZoneExh = state->dataLoopNodes->Node(3).MassFlowRate; - state->dataLoopNodes->Node(3).HumRat = state->dataHeatBalFanSys->ZoneW1(1); + state->dataLoopNodes->Node(3).HumRat = thisZoneHB.ZoneW1; state->dataLoopNodes->Node(4).MassFlowRate = 0.03; // Zone return node state->dataLoopNodes->Node(4).HumRat = 0.000; state->dataLoopNodes->Node(5).HumRat = 0.000; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.008; - state->dataHeatBalFanSys->OAMFL(1) = 0.0; - state->dataHeatBalFanSys->VAMFL(1) = 0.0; - state->dataHeatBalFanSys->EAMFL(1) = 0.0; - state->dataHeatBalFanSys->EAMFLxHumRat(1) = 0.0; - state->dataHeatBalFanSys->CTMFL(1) = 0.0; + thisZoneHB.ZoneAirHumRat = 0.008; + thisZoneHB.OAMFL = 0.0; + thisZoneHB.VAMFL = 0.0; + thisZoneHB.EAMFL = 0.0; + thisZoneHB.EAMFLxHumRat = 0.0; + thisZoneHB.CTMFL = 0.0; state->dataEnvrn->OutHumRat = 0.008; - state->dataHeatBalFanSys->MixingMassFlowXHumRat(1) = 0.0; - state->dataHeatBalFanSys->MixingMassFlowZone(1) = 0.0; - state->dataHeatBalFanSys->MDotOA(1) = 0.0; + thisZoneHB.MixingMassFlowXHumRat = 0.0; + thisZoneHB.MixingMassFlowZone = 0.0; + thisZoneHB.MDotOA = 0.0; - // HybridModel - state->dataHybridModel->HybridModelZone(1).PeopleCountCalc_H = false; - - CorrectZoneHumRat(*state, 1); + thisZoneHB.correctHumRat(*state, 1); EXPECT_NEAR(0.008, state->dataLoopNodes->Node(5).HumRat, 0.00001); // Case 2 - Unbalanced exhaust flow - state->dataHeatBalFanSys->ZoneW1(1) = 0.008; + thisZoneHB.ZoneW1 = 0.008; state->dataLoopNodes->Node(1).MassFlowRate = 0.01; // Zone inlet node 1 state->dataLoopNodes->Node(1).HumRat = 0.008; state->dataLoopNodes->Node(2).MassFlowRate = 0.02; // Zone inlet node 2 @@ -205,26 +189,26 @@ TEST_F(EnergyPlusFixture, ZoneTempPredictorCorrector_CorrectZoneHumRatTest) state->dataZoneEquip->ZoneEquipConfig(1).ZoneExhBalanced = 0.0; state->dataLoopNodes->Node(3).MassFlowRate = 0.02; // Zone exhaust node 1 state->dataZoneEquip->ZoneEquipConfig(1).ZoneExh = state->dataLoopNodes->Node(3).MassFlowRate; - state->dataLoopNodes->Node(3).HumRat = state->dataHeatBalFanSys->ZoneW1(1); + state->dataLoopNodes->Node(3).HumRat = thisZoneHB.ZoneW1; state->dataLoopNodes->Node(4).MassFlowRate = 0.01; // Zone return node - state->dataLoopNodes->Node(4).HumRat = state->dataHeatBalFanSys->ZoneW1(1); + state->dataLoopNodes->Node(4).HumRat = thisZoneHB.ZoneW1; state->dataLoopNodes->Node(5).HumRat = 0.000; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.008; - state->dataHeatBalFanSys->OAMFL(1) = 0.0; - state->dataHeatBalFanSys->VAMFL(1) = 0.0; - state->dataHeatBalFanSys->EAMFL(1) = 0.0; - state->dataHeatBalFanSys->EAMFLxHumRat(1) = 0.0; - state->dataHeatBalFanSys->CTMFL(1) = 0.0; + thisZoneHB.ZoneAirHumRat = 0.008; + thisZoneHB.OAMFL = 0.0; + thisZoneHB.VAMFL = 0.0; + thisZoneHB.EAMFL = 0.0; + thisZoneHB.EAMFLxHumRat = 0.0; + thisZoneHB.CTMFL = 0.0; state->dataEnvrn->OutHumRat = 0.004; - state->dataHeatBalFanSys->MixingMassFlowXHumRat(1) = 0.0; - state->dataHeatBalFanSys->MixingMassFlowZone(1) = 0.0; - state->dataHeatBalFanSys->MDotOA(1) = 0.0; + thisZoneHB.MixingMassFlowXHumRat = 0.0; + thisZoneHB.MixingMassFlowZone = 0.0; + thisZoneHB.MDotOA = 0.0; - CorrectZoneHumRat(*state, 1); + thisZoneHB.correctHumRat(*state, 1); EXPECT_NEAR(0.008, state->dataLoopNodes->Node(5).HumRat, 0.00001); // Case 3 - Balanced exhaust flow with proper source flow from mixing - state->dataHeatBalFanSys->ZoneW1(1) = 0.008; + thisZoneHB.ZoneW1 = 0.008; state->dataLoopNodes->Node(1).MassFlowRate = 0.01; // Zone inlet node 1 state->dataLoopNodes->Node(1).HumRat = 0.008; state->dataLoopNodes->Node(2).MassFlowRate = 0.02; // Zone inlet node 2 @@ -232,26 +216,26 @@ TEST_F(EnergyPlusFixture, ZoneTempPredictorCorrector_CorrectZoneHumRatTest) state->dataZoneEquip->ZoneEquipConfig(1).ZoneExhBalanced = 0.02; state->dataLoopNodes->Node(3).MassFlowRate = 0.02; // Zone exhaust node 1 state->dataZoneEquip->ZoneEquipConfig(1).ZoneExh = state->dataLoopNodes->Node(3).MassFlowRate; - state->dataLoopNodes->Node(3).HumRat = state->dataHeatBalFanSys->ZoneW1(1); + state->dataLoopNodes->Node(3).HumRat = thisZoneHB.ZoneW1; state->dataLoopNodes->Node(4).MassFlowRate = 0.03; // Zone return node - state->dataLoopNodes->Node(4).HumRat = state->dataHeatBalFanSys->ZoneW1(1); + state->dataLoopNodes->Node(4).HumRat = thisZoneHB.ZoneW1; state->dataLoopNodes->Node(5).HumRat = 0.000; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.008; - state->dataHeatBalFanSys->OAMFL(1) = 0.0; - state->dataHeatBalFanSys->VAMFL(1) = 0.0; - state->dataHeatBalFanSys->EAMFL(1) = 0.0; - state->dataHeatBalFanSys->EAMFLxHumRat(1) = 0.0; - state->dataHeatBalFanSys->CTMFL(1) = 0.0; + thisZoneHB.ZoneAirHumRat = 0.008; + thisZoneHB.OAMFL = 0.0; + thisZoneHB.VAMFL = 0.0; + thisZoneHB.EAMFL = 0.0; + thisZoneHB.EAMFLxHumRat = 0.0; + thisZoneHB.CTMFL = 0.0; state->dataEnvrn->OutHumRat = 0.004; - state->dataHeatBalFanSys->MixingMassFlowXHumRat(1) = 0.02 * 0.008; - state->dataHeatBalFanSys->MixingMassFlowZone(1) = 0.02; - state->dataHeatBalFanSys->MDotOA(1) = 0.0; + thisZoneHB.MixingMassFlowXHumRat = 0.02 * 0.008; + thisZoneHB.MixingMassFlowZone = 0.02; + thisZoneHB.MDotOA = 0.0; - CorrectZoneHumRat(*state, 1); + thisZoneHB.correctHumRat(*state, 1); EXPECT_NEAR(0.008, state->dataLoopNodes->Node(5).HumRat, 0.00001); // Case 4 - Balanced exhaust flow without source flow from mixing - state->dataHeatBalFanSys->ZoneW1(1) = 0.008; + thisZoneHB.ZoneW1 = 0.008; state->dataLoopNodes->Node(1).MassFlowRate = 0.01; // Zone inlet node 1 state->dataLoopNodes->Node(1).HumRat = 0.008; state->dataLoopNodes->Node(2).MassFlowRate = 0.02; // Zone inlet node 2 @@ -259,31 +243,31 @@ TEST_F(EnergyPlusFixture, ZoneTempPredictorCorrector_CorrectZoneHumRatTest) state->dataZoneEquip->ZoneEquipConfig(1).ZoneExhBalanced = 0.02; state->dataLoopNodes->Node(3).MassFlowRate = 0.02; // Zone exhaust node 1 state->dataZoneEquip->ZoneEquipConfig(1).ZoneExh = state->dataLoopNodes->Node(3).MassFlowRate; - state->dataLoopNodes->Node(3).HumRat = state->dataHeatBalFanSys->ZoneW1(1); + state->dataLoopNodes->Node(3).HumRat = thisZoneHB.ZoneW1; state->dataLoopNodes->Node(4).MassFlowRate = 0.01; // Zone return node - state->dataLoopNodes->Node(4).HumRat = state->dataHeatBalFanSys->ZoneW1(1); + state->dataLoopNodes->Node(4).HumRat = thisZoneHB.ZoneW1; state->dataLoopNodes->Node(5).HumRat = 0.000; - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.008; - state->dataHeatBalFanSys->OAMFL(1) = 0.0; - state->dataHeatBalFanSys->VAMFL(1) = 0.0; - state->dataHeatBalFanSys->EAMFL(1) = 0.0; - state->dataHeatBalFanSys->EAMFLxHumRat(1) = 0.0; - state->dataHeatBalFanSys->CTMFL(1) = 0.0; + thisZoneHB.ZoneAirHumRat = 0.008; + thisZoneHB.OAMFL = 0.0; + thisZoneHB.VAMFL = 0.0; + thisZoneHB.EAMFL = 0.0; + thisZoneHB.EAMFLxHumRat = 0.0; + thisZoneHB.CTMFL = 0.0; state->dataEnvrn->OutHumRat = 0.004; - state->dataHeatBalFanSys->MixingMassFlowXHumRat(1) = 0.0; - state->dataHeatBalFanSys->MixingMassFlowZone(1) = 0.0; - state->dataHeatBalFanSys->MDotOA(1) = 0.0; + thisZoneHB.MixingMassFlowXHumRat = 0.0; + thisZoneHB.MixingMassFlowZone = 0.0; + thisZoneHB.MDotOA = 0.0; - CorrectZoneHumRat(*state, 1); + thisZoneHB.correctHumRat(*state, 1); EXPECT_NEAR(0.008, state->dataLoopNodes->Node(5).HumRat, 0.00001); // Add a section to check #6119 by L. Gu on 5/16/17 - CorrectZoneHumRat(*state, 1); + thisZoneHB.correctHumRat(*state, 1); EXPECT_NEAR(0.008, state->dataLoopNodes->Node(5).HumRat, 0.00001); // Issue 6233 state->dataHeatBal->Zone(1).IsControlled = true; - CorrectZoneHumRat(*state, 1); + thisZoneHB.correctHumRat(*state, 1); EXPECT_NEAR(0.008, state->dataLoopNodes->Node(5).HumRat, 0.00001); } @@ -485,20 +469,13 @@ TEST_F(EnergyPlusFixture, ZoneTempPredictorCorrector_ReportingTest) state->dataHeatBalFanSys->TempControlTypeRpt.allocate(state->dataZoneCtrls->NumTempControlledZones); state->dataZoneEnergyDemand->ZoneSysEnergyDemand.allocate(state->dataZoneCtrls->NumTempControlledZones); state->dataHeatBalFanSys->TempZoneThermostatSetPoint.allocate(state->dataZoneCtrls->NumTempControlledZones); - state->dataZoneTempPredictorCorrector->ZoneSetPointLast.allocate(state->dataZoneCtrls->NumTempControlledZones); state->dataZoneEnergyDemand->Setback.allocate(state->dataZoneCtrls->NumTempControlledZones); state->dataHeatBalFanSys->ZoneThermostatSetPointLo.allocate(state->dataZoneCtrls->NumTempControlledZones); state->dataHeatBalFanSys->ZoneThermostatSetPointHi.allocate(state->dataZoneCtrls->NumTempControlledZones); - state->dataZoneTempPredictorCorrector->TempDepZnLd.allocate(state->dataZoneCtrls->NumTempControlledZones); - state->dataZoneTempPredictorCorrector->TempIndZnLd.allocate(state->dataZoneCtrls->NumTempControlledZones); - state->dataZoneTempPredictorCorrector->TempDepZnLd = 0.0; - state->dataZoneTempPredictorCorrector->TempIndZnLd = 0.0; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(state->dataGlobal->NumOfZones); + state->dataZoneTempPredictorCorrector->spaceHeatBalance.allocate(state->dataGlobal->NumOfZones); - state->dataHeatBal->ZoneSNLoadPredictedRate.allocate(state->dataZoneCtrls->NumTempControlledZones); state->dataHeatBalFanSys->LoadCorrectionFactor.allocate(state->dataZoneCtrls->NumTempControlledZones); - state->dataHeatBal->ZoneSNLoadPredictedHSPRate.allocate(state->dataZoneCtrls->NumTempControlledZones); - state->dataHeatBal->ZoneSNLoadPredictedCSPRate.allocate(state->dataZoneCtrls->NumTempControlledZones); - state->dataHeatBalFanSys->LoadCorrectionFactor(HeatZoneNum) = 1.0; state->dataHeatBalFanSys->LoadCorrectionFactor(CoolZoneNum) = 1.0; state->dataHeatBalFanSys->LoadCorrectionFactor(CoolHeatZoneNum) = 1.0; @@ -522,7 +499,7 @@ TEST_F(EnergyPlusFixture, ZoneTempPredictorCorrector_ReportingTest) state->dataZoneEnergyDemand->ZoneSysEnergyDemand(DualZoneNum).TotalOutputRequired = 0.0; // no load and no thermostat since control type is set to 0 above CalcZoneAirTempSetPoints(*state); - CalcPredictedSystemLoad(*state, DualZoneNum, 1.0); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(DualZoneNum).calcPredictedSystemLoad(*state, 1.0, DualZoneNum); EXPECT_EQ(0.0, state->dataHeatBalFanSys->TempZoneThermostatSetPoint( @@ -538,12 +515,12 @@ TEST_F(EnergyPlusFixture, ZoneTempPredictorCorrector_ReportingTest) int SetPointTempSchedIndex = state->dataZoneCtrls->TempControlledZone(HeatZoneNum).SchIndx_SingleHeatSetPoint; state->dataScheduleMgr->Schedule(SetPointTempSchedIndex).CurrentValue = 20.0; state->dataZoneEnergyDemand->ZoneSysEnergyDemand(HeatZoneNum).TotalOutputRequired = -1000.0; // cooling load - state->dataZoneTempPredictorCorrector->TempDepZnLd(HeatZoneNum) = + state->dataZoneTempPredictorCorrector->zoneHeatBalance(HeatZoneNum).TempDepZnLd = state->dataZoneEnergyDemand->ZoneSysEnergyDemand(HeatZoneNum).TotalOutputRequired / state->dataScheduleMgr->Schedule(SetPointTempSchedIndex).CurrentValue; CalcZoneAirTempSetPoints(*state); - CalcPredictedSystemLoad(*state, HeatZoneNum, 1.0); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(HeatZoneNum).calcPredictedSystemLoad(*state, 1.0, HeatZoneNum); EXPECT_EQ(20.0, state->dataHeatBalFanSys->TempZoneThermostatSetPoint(HeatZoneNum)); EXPECT_EQ(-1000.0, @@ -554,21 +531,21 @@ TEST_F(EnergyPlusFixture, ZoneTempPredictorCorrector_ReportingTest) SetPointTempSchedIndex = state->dataZoneCtrls->TempControlledZone(HeatZoneNum).SchIndx_SingleHeatSetPoint; state->dataScheduleMgr->Schedule(SetPointTempSchedIndex).CurrentValue = 21.0; state->dataZoneEnergyDemand->ZoneSysEnergyDemand(HeatZoneNum).TotalOutputRequired = 1000.0; // heating load - state->dataZoneTempPredictorCorrector->TempDepZnLd(HeatZoneNum) = + state->dataZoneTempPredictorCorrector->zoneHeatBalance(HeatZoneNum).TempDepZnLd = state->dataZoneEnergyDemand->ZoneSysEnergyDemand(HeatZoneNum).TotalOutputRequired / state->dataScheduleMgr->Schedule(SetPointTempSchedIndex).CurrentValue; SetPointTempSchedIndex = state->dataZoneCtrls->TempControlledZone(CoolZoneNum).SchIndx_SingleCoolSetPoint; state->dataScheduleMgr->Schedule(SetPointTempSchedIndex).CurrentValue = 23.0; state->dataZoneEnergyDemand->ZoneSysEnergyDemand(CoolZoneNum).TotalOutputRequired = -3000.0; // cooling load - state->dataZoneTempPredictorCorrector->TempDepZnLd(CoolZoneNum) = + state->dataZoneTempPredictorCorrector->zoneHeatBalance(CoolZoneNum).TempDepZnLd = state->dataZoneEnergyDemand->ZoneSysEnergyDemand(CoolZoneNum).TotalOutputRequired / state->dataScheduleMgr->Schedule(SetPointTempSchedIndex).CurrentValue; SetPointTempSchedIndex = state->dataZoneCtrls->TempControlledZone(CoolHeatZoneNum).SchIndx_SingleHeatCoolSetPoint; state->dataScheduleMgr->Schedule(SetPointTempSchedIndex).CurrentValue = 22.0; state->dataZoneEnergyDemand->ZoneSysEnergyDemand(CoolHeatZoneNum).TotalOutputRequired = -4000.0; // cooling load - state->dataZoneTempPredictorCorrector->TempDepZnLd(CoolHeatZoneNum) = + state->dataZoneTempPredictorCorrector->zoneHeatBalance(CoolHeatZoneNum).TempDepZnLd = state->dataZoneEnergyDemand->ZoneSysEnergyDemand(CoolHeatZoneNum).TotalOutputRequired / state->dataScheduleMgr->Schedule(SetPointTempSchedIndex).CurrentValue; @@ -577,12 +554,12 @@ TEST_F(EnergyPlusFixture, ZoneTempPredictorCorrector_ReportingTest) SetPointTempSchedIndex = state->dataZoneCtrls->TempControlledZone(DualZoneNum).SchIndx_DualSetPointWDeadBandHeat; state->dataScheduleMgr->Schedule(SetPointTempSchedIndex).CurrentValue = 20.0; state->dataZoneEnergyDemand->ZoneSysEnergyDemand(DualZoneNum).TotalOutputRequired = 2500.0; // heating load - state->dataZoneTempPredictorCorrector->TempDepZnLd(DualZoneNum) = + state->dataZoneTempPredictorCorrector->zoneHeatBalance(DualZoneNum).TempDepZnLd = state->dataZoneEnergyDemand->ZoneSysEnergyDemand(DualZoneNum).TotalOutputRequired / state->dataScheduleMgr->Schedule(SetPointTempSchedIndex).CurrentValue; CalcZoneAirTempSetPoints(*state); - CalcPredictedSystemLoad(*state, HeatZoneNum, 1.0); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(HeatZoneNum).calcPredictedSystemLoad(*state, 1.0, HeatZoneNum); EXPECT_EQ(21.0, state->dataHeatBalFanSys->TempZoneThermostatSetPoint(HeatZoneNum)); EXPECT_FALSE(state->dataZoneEnergyDemand->CurDeadBandOrSetback(HeatZoneNum)); // Tstat should show there is load on a single heating SP @@ -590,7 +567,7 @@ TEST_F(EnergyPlusFixture, ZoneTempPredictorCorrector_ReportingTest) state->dataZoneEnergyDemand->ZoneSysEnergyDemand(HeatZoneNum) .TotalOutputRequired); // TotalOutputRequired gets updated in CalcPredictedSystemLoad based on the load - CalcPredictedSystemLoad(*state, CoolZoneNum, 1.0); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(CoolZoneNum).calcPredictedSystemLoad(*state, 1.0, CoolZoneNum); EXPECT_EQ(23.0, state->dataHeatBalFanSys->TempZoneThermostatSetPoint(CoolZoneNum)); EXPECT_FALSE(state->dataZoneEnergyDemand->CurDeadBandOrSetback(CoolZoneNum)); // Tstat should show there is load on a single cooling SP @@ -598,7 +575,7 @@ TEST_F(EnergyPlusFixture, ZoneTempPredictorCorrector_ReportingTest) state->dataZoneEnergyDemand->ZoneSysEnergyDemand(CoolZoneNum) .TotalOutputRequired); // TotalOutputRequired gets updated in CalcPredictedSystemLoad based on the load - CalcPredictedSystemLoad(*state, CoolHeatZoneNum, 1.0); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(CoolHeatZoneNum).calcPredictedSystemLoad(*state, 1.0, CoolHeatZoneNum); ASSERT_EQ(22.0, state->dataHeatBalFanSys->TempZoneThermostatSetPoint(CoolHeatZoneNum)); EXPECT_FALSE( @@ -607,7 +584,7 @@ TEST_F(EnergyPlusFixture, ZoneTempPredictorCorrector_ReportingTest) state->dataZoneEnergyDemand->ZoneSysEnergyDemand(CoolHeatZoneNum) .TotalOutputRequired); // TotalOutputRequired gets updated in CalcPredictedSystemLoad based on the load - CalcPredictedSystemLoad(*state, DualZoneNum, 1.0); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(DualZoneNum).calcPredictedSystemLoad(*state, 1.0, DualZoneNum); EXPECT_EQ(20.0, state->dataHeatBalFanSys->TempZoneThermostatSetPoint(DualZoneNum)); EXPECT_FALSE(state->dataZoneEnergyDemand->CurDeadBandOrSetback(DualZoneNum)); // Tstat should show there is load on a dual SP @@ -619,13 +596,13 @@ TEST_F(EnergyPlusFixture, ZoneTempPredictorCorrector_ReportingTest) state->dataScheduleMgr->Schedule(SetPointTempSchedIndex).CurrentValue = 25.0; state->dataZoneEnergyDemand->ZoneSysEnergyDemand(DualZoneNum).TotalOutputRequired = 1000.0; // LoadToCoolingSetPoint = ( TempDepZnLd( ZoneNum ) * ( TempZoneThermostatSetPoint( ZoneNum ) ) - TempIndZnLd( ZoneNum ) ); - state->dataZoneTempPredictorCorrector->TempDepZnLd(DualZoneNum) = + state->dataZoneTempPredictorCorrector->zoneHeatBalance(DualZoneNum).TempDepZnLd = state->dataZoneEnergyDemand->ZoneSysEnergyDemand(DualZoneNum).TotalOutputRequired / state->dataScheduleMgr->Schedule(SetPointTempSchedIndex).CurrentValue; - state->dataZoneTempPredictorCorrector->TempIndZnLd(DualZoneNum) = 3500.0; // results in a cooling load + state->dataZoneTempPredictorCorrector->zoneHeatBalance(DualZoneNum).TempIndZnLd = 3500.0; // results in a cooling load CalcZoneAirTempSetPoints(*state); - CalcPredictedSystemLoad(*state, DualZoneNum, 1.0); + state->dataZoneTempPredictorCorrector->zoneHeatBalance(DualZoneNum).calcPredictedSystemLoad(*state, 1.0, DualZoneNum); EXPECT_EQ(25.0, state->dataHeatBalFanSys->TempZoneThermostatSetPoint(DualZoneNum)); EXPECT_FALSE(state->dataZoneEnergyDemand->CurDeadBandOrSetback(DualZoneNum)); // Tstat should show there is load on a dual SP @@ -953,47 +930,17 @@ TEST_F(EnergyPlusFixture, ZoneTempPredictorCorrector_AdaptiveThermostat) ASSERT_EQ(26.0, ZoneAirSetPoint); // Tstat should show set point is not overwritten } -TEST_F(EnergyPlusFixture, ZoneTempPredictorCorrector_CalcZoneSums_SurfConvectionTest) +TEST_F(EnergyPlusFixture, ZoneTempPredictorCorrector_calcZoneOrSpaceSums_SurfConvectionTest) { // AUTHOR: L. Gu, FSEC // DATE WRITTEN: Jan 2017 // #5906 Adaptive convection resulting in extremely low zone temperature which causes fatal error - int ZoneNum = 1; // Zone number - Real64 SumIntGain = 0.0; // Zone sum of convective internal gains - Real64 SumHA = 0.0; // Zone sum of Hc*Area - Real64 SumHATsurf = 0.0; // Zone sum of Hc*Area*Tsurf - Real64 SumHATref = 0.0; // Zone sum of Hc*Area*Tref, for ceiling diffuser convection correlation - Real64 SumMCp = 0.0; // Zone sum of MassFlowRate*Cp - Real64 SumMCpT = 0.0; // Zone sum of MassFlowRate*Cp*T - Real64 SumSysMCp = 0.0; // Zone sum of air system MassFlowRate*Cp - Real64 SumSysMCpT = 0.0; // Zone sum of air system MassFlowRate*Cp*T + int ZoneNum = 1; // Zone number state->dataHeatBal->ZoneIntGain.allocate(ZoneNum); state->dataHeatBalFanSys->SumConvHTRadSys.allocate(ZoneNum); state->dataHeatBalFanSys->SumConvPool.allocate(ZoneNum); - state->dataHeatBalFanSys->MCPI.allocate(ZoneNum); - state->dataHeatBalFanSys->MCPV.allocate(ZoneNum); - state->dataHeatBalFanSys->MCPM.allocate(ZoneNum); - state->dataHeatBalFanSys->MCPE.allocate(ZoneNum); - state->dataHeatBalFanSys->MCPC.allocate(ZoneNum); - state->dataHeatBalFanSys->MCPTI.allocate(ZoneNum); - state->dataHeatBalFanSys->MCPTV.allocate(ZoneNum); - state->dataHeatBalFanSys->MCPTM.allocate(ZoneNum); - state->dataHeatBalFanSys->MCPTE.allocate(ZoneNum); - state->dataHeatBalFanSys->MCPTC.allocate(ZoneNum); - state->dataHeatBalFanSys->MDotCPOA.allocate(ZoneNum); - state->dataHeatBalFanSys->MCPI(ZoneNum) = 0.0; - state->dataHeatBalFanSys->MCPV(ZoneNum) = 0.0; - state->dataHeatBalFanSys->MCPM(ZoneNum) = 0.0; - state->dataHeatBalFanSys->MCPE(ZoneNum) = 0.0; - state->dataHeatBalFanSys->MCPC(ZoneNum) = 0.0; - state->dataHeatBalFanSys->MCPTI(ZoneNum) = 0.0; - state->dataHeatBalFanSys->MCPTV(ZoneNum) = 0.0; - state->dataHeatBalFanSys->MCPTM(ZoneNum) = 0.0; - state->dataHeatBalFanSys->MCPTE(ZoneNum) = 0.0; - state->dataHeatBalFanSys->MCPTC(ZoneNum) = 0.0; - state->dataHeatBalFanSys->MDotCPOA(ZoneNum) = 0.0; state->dataHeatBalFanSys->SumConvHTRadSys(1) = 0.0; state->dataHeatBalFanSys->SumConvPool(1) = 0.0; @@ -1022,20 +969,22 @@ TEST_F(EnergyPlusFixture, ZoneTempPredictorCorrector_CalcZoneSums_SurfConvection state->dataHeatBal->Zone(1).Volume = 1000.0; state->dataHeatBal->Zone(1).SystemZoneNodeNumber = 5; state->dataHeatBal->Zone(1).ZoneVolCapMultpMoist = 1.0; - state->dataHeatBalFanSys->ZoneLatentGain.allocate(1); - state->dataHeatBalFanSys->ZoneLatentGain(1) = 0.0; state->dataHeatBalFanSys->SumLatentHTRadSys.allocate(1); state->dataHeatBalFanSys->SumLatentHTRadSys(1) = 0.0; state->dataHeatBalFanSys->SumLatentPool.allocate(1); state->dataHeatBalFanSys->SumLatentPool(1) = 0.0; state->dataEnvrn->OutBaroPress = 101325.0; - state->dataHeatBalFanSys->MAT.allocate(1); // Zone temperature C - state->dataHeatBalFanSys->MAT(1) = 24.0; - state->dataHeatBalFanSys->ZoneAirHumRat.allocate(1); - state->dataHeatBalFanSys->ZoneAirHumRat(1) = 0.001; - - state->dataHeatBal->Zone(1).HTSurfaceFirst = 1; - state->dataHeatBal->Zone(1).HTSurfaceLast = 3; + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->spaceHeatBalance.allocate(1); + auto &thisZoneHB = state->dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum); + thisZoneHB.MAT = 24.0; + thisZoneHB.ZoneAirHumRat = 0.001; + + state->dataHeatBal->space.allocate(1); + state->dataHeatBal->spaceIntGainDevices.allocate(1); + state->dataHeatBal->Zone(1).spaceIndexes.emplace_back(1); + state->dataHeatBal->space(1).HTSurfaceFirst = 1; + state->dataHeatBal->space(1).HTSurfaceLast = 3; state->dataSurface->Surface.allocate(3); state->dataHeatBalSurf->SurfHConvInt.allocate(3); state->dataLoopNodes->Node.allocate(4); @@ -1076,27 +1025,28 @@ TEST_F(EnergyPlusFixture, ZoneTempPredictorCorrector_CalcZoneSums_SurfConvection state->dataZonePlenum->NumZoneReturnPlenums = 0; state->dataZonePlenum->NumZoneSupplyPlenums = 0; - CalcZoneSums(*state, ZoneNum, SumIntGain, SumHA, SumHATsurf, SumHATref, SumMCp, SumMCpT, SumSysMCp, SumSysMCpT); - EXPECT_EQ(5.0, SumHA); - EXPECT_EQ(300.0, SumHATsurf); - EXPECT_EQ(150.0, SumHATref); + thisZoneHB.calcZoneOrSpaceSums(*state, true, ZoneNum); + + EXPECT_EQ(5.0, thisZoneHB.SumHA); + EXPECT_EQ(300.0, thisZoneHB.SumHATsurf); + EXPECT_EQ(150.0, thisZoneHB.SumHATref); state->dataLoopNodes->Node(1).MassFlowRate = 0.0; state->dataLoopNodes->Node(2).MassFlowRate = 0.0; - CalcZoneSums(*state, ZoneNum, SumIntGain, SumHA, SumHATsurf, SumHATref, SumMCp, SumMCpT, SumSysMCp, SumSysMCpT); - EXPECT_EQ(10.0, SumHA); - EXPECT_EQ(300.0, SumHATsurf); - EXPECT_EQ(50.0, SumHATref); + thisZoneHB.calcZoneOrSpaceSums(*state, true, ZoneNum); + EXPECT_EQ(10.0, thisZoneHB.SumHA); + EXPECT_EQ(300.0, thisZoneHB.SumHATsurf); + EXPECT_EQ(50.0, thisZoneHB.SumHATref); state->dataLoopNodes->Node(1).MassFlowRate = 0.1; state->dataLoopNodes->Node(2).MassFlowRate = 0.2; - CalcZoneSums(*state, ZoneNum, SumIntGain, SumHA, SumHATsurf, SumHATref, SumMCp, SumMCpT, SumSysMCp, SumSysMCpT); - EXPECT_NEAR(302.00968500, SumSysMCp, 0.0001); - EXPECT_NEAR(6040.1937, SumSysMCpT, 0.0001); + thisZoneHB.calcZoneOrSpaceSums(*state, true, ZoneNum); + EXPECT_NEAR(302.00968500, thisZoneHB.SumSysMCp, 0.0001); + EXPECT_NEAR(6040.1937, thisZoneHB.SumSysMCpT, 0.0001); - CalcZoneSums(*state, ZoneNum, SumIntGain, SumHA, SumHATsurf, SumHATref, SumMCp, SumMCpT, SumSysMCp, SumSysMCpT, false); - EXPECT_EQ(0.0, SumSysMCp); - EXPECT_EQ(0.0, SumSysMCpT); + thisZoneHB.calcZoneOrSpaceSums(*state, false, ZoneNum); + EXPECT_EQ(0.0, thisZoneHB.SumSysMCp); + EXPECT_EQ(0.0, thisZoneHB.SumSysMCpT); } TEST_F(EnergyPlusFixture, ZoneTempPredictorCorrector_EMSOverrideSetpointTest) @@ -1254,22 +1204,13 @@ TEST_F(EnergyPlusFixture, SetPointWithCutoutDeltaT_test) // SingleHeatingSetPoint state->dataZoneCtrls->TempControlledZone.allocate(state->dataZoneCtrls->NumTempControlledZones); state->dataHeatBalFanSys->TempZoneThermostatSetPoint.allocate(1); - state->dataHeatBalFanSys->MAT.allocate(1); state->dataHeatBalFanSys->ZoneThermostatSetPointLo.allocate(1); state->dataHeatBalFanSys->ZoneThermostatSetPointHi.allocate(1); - state->dataHeatBalFanSys->ZoneT1.allocate(1); state->dataZoneEnergyDemand->ZoneSysEnergyDemand.allocate(1); - state->dataHeatBalFanSys->AIRRAT.allocate(1); - state->dataZoneTempPredictorCorrector->TempDepZnLd.allocate(1); - state->dataZoneTempPredictorCorrector->TempIndZnLd.allocate(1); state->dataZoneEnergyDemand->DeadBandOrSetback.allocate(1); state->dataHeatBal->Zone.allocate(1); - state->dataZoneTempPredictorCorrector->ZoneSetPointLast.allocate(1); state->dataZoneEnergyDemand->Setback.allocate(1); - state->dataHeatBal->ZoneSNLoadPredictedRate.allocate(1); - state->dataHeatBal->ZoneSNLoadPredictedHSPRate.allocate(1); - state->dataHeatBal->ZoneSNLoadPredictedCSPRate.allocate(1); state->dataZoneEnergyDemand->CurDeadBandOrSetback.allocate(1); state->dataHeatBalFanSys->LoadCorrectionFactor.allocate(1); state->dataZoneEnergyDemand->DeadBandOrSetback.allocate(1); @@ -1286,19 +1227,23 @@ TEST_F(EnergyPlusFixture, SetPointWithCutoutDeltaT_test) state->dataZoneTempPredictorCorrector->SetPointSingleHeating.allocate(1); state->dataZoneTempPredictorCorrector->SetPointSingleHeating(1).TempSchedIndex = 3; state->dataScheduleMgr->Schedule(3).CurrentValue = 22.0; - state->dataHeatBalFanSys->AIRRAT(1) = 2000; - state->dataZoneTempPredictorCorrector->TempDepZnLd(1) = 1.0; - state->dataZoneTempPredictorCorrector->TempIndZnLd(1) = 1.0; - state->dataHeatBalFanSys->MAT(1) = 20.0; - state->dataHeatBalFanSys->ZoneT1(1) = state->dataHeatBalFanSys->MAT(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->spaceHeatBalance.allocate(1); + auto &thisZoneHB = state->dataZoneTempPredictorCorrector->zoneHeatBalance(1); + thisZoneHB.AirPowerCap = 2000; + thisZoneHB.TempDepZnLd = 1.0; + thisZoneHB.TempIndZnLd = 1.0; + + thisZoneHB.MAT = 20.0; + thisZoneHB.ZoneT1 = thisZoneHB.MAT; state->dataZoneTempPredictorCorrector->NumOnOffCtrZone = 1; CalcZoneAirTempSetPoints(*state); PredictSystemLoads(*state, false, false, 0.01); EXPECT_EQ(24.0, state->dataHeatBalFanSys->ZoneThermostatSetPointLo(1)); - state->dataHeatBalFanSys->MAT(1) = 23.0; - state->dataHeatBalFanSys->ZoneT1(1) = state->dataHeatBalFanSys->MAT(1); + thisZoneHB.MAT = 23.0; + thisZoneHB.ZoneT1 = thisZoneHB.MAT; state->dataZoneCtrls->TempControlledZone(1).HeatModeLast = true; CalcZoneAirTempSetPoints(*state); PredictSystemLoads(*state, false, false, 0.01); @@ -1311,8 +1256,8 @@ TEST_F(EnergyPlusFixture, SetPointWithCutoutDeltaT_test) state->dataZoneTempPredictorCorrector->SetPointSingleCooling.allocate(1); state->dataZoneTempPredictorCorrector->SetPointSingleCooling(1).TempSchedIndex = 3; state->dataScheduleMgr->Schedule(3).CurrentValue = 26.0; - state->dataHeatBalFanSys->MAT(1) = 25.0; - state->dataHeatBalFanSys->ZoneT1(1) = state->dataHeatBalFanSys->MAT(1); + thisZoneHB.MAT = 25.0; + thisZoneHB.ZoneT1 = thisZoneHB.MAT; state->dataZoneCtrls->TempControlledZone(1).CoolModeLast = true; CalcZoneAirTempSetPoints(*state); @@ -1320,8 +1265,8 @@ TEST_F(EnergyPlusFixture, SetPointWithCutoutDeltaT_test) EXPECT_EQ(26.0, state->dataHeatBalFanSys->ZoneThermostatSetPointHi(1)); state->dataZoneCtrls->TempControlledZone(1).CoolModeLast = false; - state->dataHeatBalFanSys->MAT(1) = 27.0; - state->dataHeatBalFanSys->ZoneT1(1) = state->dataHeatBalFanSys->MAT(1); + thisZoneHB.MAT = 27.0; + thisZoneHB.ZoneT1 = thisZoneHB.MAT; CalcZoneAirTempSetPoints(*state); PredictSystemLoads(*state, false, false, 0.01); EXPECT_EQ(24.0, state->dataHeatBalFanSys->ZoneThermostatSetPointHi(1)); @@ -1332,8 +1277,8 @@ TEST_F(EnergyPlusFixture, SetPointWithCutoutDeltaT_test) state->dataZoneTempPredictorCorrector->SetPointSingleHeatCool.allocate(1); state->dataZoneTempPredictorCorrector->SetPointSingleHeatCool(1).TempSchedIndex = 3; state->dataScheduleMgr->Schedule(3).CurrentValue = 24.0; - state->dataHeatBalFanSys->MAT(1) = 25.0; - state->dataHeatBalFanSys->ZoneT1(1) = state->dataHeatBalFanSys->MAT(1); + thisZoneHB.MAT = 25.0; + thisZoneHB.ZoneT1 = thisZoneHB.MAT; CalcZoneAirTempSetPoints(*state); PredictSystemLoads(*state, false, false, 0.01); @@ -1349,8 +1294,8 @@ TEST_F(EnergyPlusFixture, SetPointWithCutoutDeltaT_test) state->dataZoneTempPredictorCorrector->SetPointDualHeatCool(1).CoolTempSchedIndex = 3; state->dataScheduleMgr->Schedule(2).CurrentValue = 22.0; state->dataScheduleMgr->Schedule(3).CurrentValue = 26.0; - state->dataHeatBalFanSys->MAT(1) = 25.0; - state->dataHeatBalFanSys->ZoneT1(1) = state->dataHeatBalFanSys->MAT(1); + thisZoneHB.MAT = 25.0; + thisZoneHB.ZoneT1 = thisZoneHB.MAT; state->dataZoneCtrls->TempControlledZone(1).CoolModeLast = true; state->dataZoneCtrls->TempControlledZone(1).HeatModeLast = true; @@ -1361,8 +1306,8 @@ TEST_F(EnergyPlusFixture, SetPointWithCutoutDeltaT_test) state->dataZoneCtrls->TempControlledZone(1).HeatModeLast = false; // DualSetPointWithDeadBand : Adjust heating setpoint - state->dataHeatBalFanSys->MAT(1) = 21.0; - state->dataHeatBalFanSys->ZoneT1(1) = state->dataHeatBalFanSys->MAT(1); + thisZoneHB.MAT = 21.0; + thisZoneHB.ZoneT1 = thisZoneHB.MAT; CalcZoneAirTempSetPoints(*state); PredictSystemLoads(*state, false, false, 0.01); EXPECT_EQ(24.0, state->dataHeatBalFanSys->ZoneThermostatSetPointLo(1)); @@ -1370,8 +1315,8 @@ TEST_F(EnergyPlusFixture, SetPointWithCutoutDeltaT_test) // DualSetPointWithDeadBand : Adjust cooling setpoint state->dataZoneCtrls->TempControlledZone(1).CoolModeLast = true; - state->dataHeatBalFanSys->MAT(1) = 27.0; - state->dataHeatBalFanSys->ZoneT1(1) = state->dataHeatBalFanSys->MAT(1); + thisZoneHB.MAT = 27.0; + thisZoneHB.ZoneT1 = thisZoneHB.MAT; CalcZoneAirTempSetPoints(*state); PredictSystemLoads(*state, false, false, 0.01); EXPECT_EQ(22.0, state->dataHeatBalFanSys->ZoneThermostatSetPointLo(1)); @@ -1386,22 +1331,13 @@ TEST_F(EnergyPlusFixture, TempAtPrevTimeStepWithCutoutDeltaT_test) // SingleHeatingSetPoint state->dataZoneCtrls->TempControlledZone.allocate(state->dataZoneCtrls->NumTempControlledZones); state->dataHeatBalFanSys->TempZoneThermostatSetPoint.allocate(1); - state->dataHeatBalFanSys->MAT.allocate(1); state->dataHeatBalFanSys->ZoneThermostatSetPointLo.allocate(1); state->dataHeatBalFanSys->ZoneThermostatSetPointHi.allocate(1); - state->dataHeatBalFanSys->XMPT.allocate(1); state->dataZoneEnergyDemand->ZoneSysEnergyDemand.allocate(1); - state->dataHeatBalFanSys->AIRRAT.allocate(1); - state->dataZoneTempPredictorCorrector->TempDepZnLd.allocate(1); - state->dataZoneTempPredictorCorrector->TempIndZnLd.allocate(1); state->dataZoneEnergyDemand->DeadBandOrSetback.allocate(1); state->dataHeatBal->Zone.allocate(1); - state->dataZoneTempPredictorCorrector->ZoneSetPointLast.allocate(1); state->dataZoneEnergyDemand->Setback.allocate(1); - state->dataHeatBal->ZoneSNLoadPredictedRate.allocate(1); - state->dataHeatBal->ZoneSNLoadPredictedHSPRate.allocate(1); - state->dataHeatBal->ZoneSNLoadPredictedCSPRate.allocate(1); state->dataZoneEnergyDemand->CurDeadBandOrSetback.allocate(1); state->dataHeatBalFanSys->LoadCorrectionFactor.allocate(1); state->dataZoneEnergyDemand->DeadBandOrSetback.allocate(1); @@ -1418,11 +1354,15 @@ TEST_F(EnergyPlusFixture, TempAtPrevTimeStepWithCutoutDeltaT_test) state->dataZoneTempPredictorCorrector->SetPointSingleHeating.allocate(1); state->dataZoneTempPredictorCorrector->SetPointSingleHeating(1).TempSchedIndex = 3; state->dataScheduleMgr->Schedule(3).CurrentValue = 22.0; - state->dataHeatBalFanSys->AIRRAT(1) = 2000; - state->dataZoneTempPredictorCorrector->TempDepZnLd(1) = 1.0; - state->dataZoneTempPredictorCorrector->TempIndZnLd(1) = 1.0; - state->dataHeatBalFanSys->MAT(1) = 20.0; - state->dataHeatBalFanSys->XMPT(1) = 23.0; + state->dataZoneTempPredictorCorrector->spaceHeatBalance.allocate(1); + state->dataZoneTempPredictorCorrector->zoneHeatBalance.allocate(1); + auto &thisZoneHB = state->dataZoneTempPredictorCorrector->zoneHeatBalance(1); + thisZoneHB.AirPowerCap = 2000; + thisZoneHB.TempDepZnLd = 1.0; + thisZoneHB.TempIndZnLd = 1.0; + + thisZoneHB.MAT = 20.0; + thisZoneHB.XMPT = 23.0; state->dataZoneTempPredictorCorrector->NumOnOffCtrZone = 1; CalcZoneAirTempSetPoints(*state); @@ -1440,8 +1380,8 @@ TEST_F(EnergyPlusFixture, TempAtPrevTimeStepWithCutoutDeltaT_test) state->dataZoneTempPredictorCorrector->SetPointSingleCooling.allocate(1); state->dataZoneTempPredictorCorrector->SetPointSingleCooling(1).TempSchedIndex = 3; state->dataScheduleMgr->Schedule(3).CurrentValue = 26.0; - state->dataHeatBalFanSys->MAT(1) = 25.0; - state->dataHeatBalFanSys->XMPT(1) = 27; + thisZoneHB.MAT = 25.0; + thisZoneHB.XMPT = 27; state->dataZoneCtrls->TempControlledZone(1).CoolModeLast = true; CalcZoneAirTempSetPoints(*state); @@ -1460,8 +1400,8 @@ TEST_F(EnergyPlusFixture, TempAtPrevTimeStepWithCutoutDeltaT_test) state->dataZoneTempPredictorCorrector->SetPointSingleHeatCool.allocate(1); state->dataZoneTempPredictorCorrector->SetPointSingleHeatCool(1).TempSchedIndex = 3; state->dataScheduleMgr->Schedule(3).CurrentValue = 24.0; - state->dataHeatBalFanSys->MAT(1) = 25.0; - state->dataHeatBalFanSys->XMPT(1) = state->dataHeatBalFanSys->MAT(1); + thisZoneHB.MAT = 25.0; + thisZoneHB.XMPT = thisZoneHB.MAT; CalcZoneAirTempSetPoints(*state); PredictSystemLoads(*state, false, false, 0.01); @@ -1477,8 +1417,8 @@ TEST_F(EnergyPlusFixture, TempAtPrevTimeStepWithCutoutDeltaT_test) state->dataZoneTempPredictorCorrector->SetPointDualHeatCool(1).CoolTempSchedIndex = 3; state->dataScheduleMgr->Schedule(2).CurrentValue = 22.0; state->dataScheduleMgr->Schedule(3).CurrentValue = 26.0; - state->dataHeatBalFanSys->MAT(1) = 25.0; - state->dataHeatBalFanSys->XMPT(1) = 21.0; + thisZoneHB.MAT = 25.0; + thisZoneHB.XMPT = 21.0; state->dataZoneCtrls->TempControlledZone(1).CoolModeLast = true; state->dataZoneCtrls->TempControlledZone(1).HeatModeLast = true; @@ -1497,7 +1437,7 @@ TEST_F(EnergyPlusFixture, TempAtPrevTimeStepWithCutoutDeltaT_test) // DualSetPointWithDeadBand : Adjust cooling setpoint state->dataZoneCtrls->TempControlledZone(1).CoolModeLastSave = true; - state->dataHeatBalFanSys->XMPT(1) = 27.0; + thisZoneHB.XMPT = 27.0; CalcZoneAirTempSetPoints(*state); PredictSystemLoads(*state, true, false, 0.01); EXPECT_EQ(22.0, state->dataHeatBalFanSys->ZoneThermostatSetPointLo(1)); @@ -1506,153 +1446,127 @@ TEST_F(EnergyPlusFixture, TempAtPrevTimeStepWithCutoutDeltaT_test) TEST_F(EnergyPlusFixture, ReportMoistLoadsZoneMultiplier_Test) { - Real64 TotOutReq; - Real64 OutReqToHumSP; - Real64 OutReqToDehumSP; - Real64 SingleZoneTotRate; - Real64 SingleZoneHumRate; - Real64 SingleZoneDehRate; - Real64 ZoneMultiplier; - Real64 ZoneMultiplierList; + int zoneNum = 1; + state->dataZoneEnergyDemand->ZoneSysMoistureDemand.allocate(zoneNum); + auto &thisZoneSysMoistureDemand = state->dataZoneEnergyDemand->ZoneSysMoistureDemand(zoneNum); + state->dataHeatBal->Zone.allocate(zoneNum); + auto &thisZone = state->dataHeatBal->Zone(zoneNum); Real64 ExpectedResult; Real64 AcceptableTolerance = 0.00001; // Test 1: Zone Multipliers are all unity (1.0). So, single zone loads should be the same as total loads - TotOutReq = 1000.0; - OutReqToHumSP = 2000.0; - OutReqToDehumSP = 3000.0; - ZoneMultiplier = 1.0; - ZoneMultiplierList = 1.0; - ReportMoistLoadsZoneMultiplier( - TotOutReq, OutReqToHumSP, OutReqToDehumSP, SingleZoneTotRate, SingleZoneHumRate, SingleZoneDehRate, ZoneMultiplier, ZoneMultiplierList); - EXPECT_NEAR(TotOutReq, SingleZoneTotRate, AcceptableTolerance); - EXPECT_NEAR(OutReqToHumSP, SingleZoneHumRate, AcceptableTolerance); - EXPECT_NEAR(OutReqToDehumSP, SingleZoneDehRate, AcceptableTolerance); + Real64 totalOutputRequired = 1000.0; + Real64 outputRequiredToHumidifyingSP = 2000.0; + Real64 outputRequiredToDehumidifyingSP = 3000.0; + thisZone.Multiplier = 1.0; + thisZone.ListMultiplier = 1.0; + thisZoneSysMoistureDemand.reportMoistLoadsZoneMultiplier( + *state, zoneNum, totalOutputRequired, outputRequiredToHumidifyingSP, outputRequiredToDehumidifyingSP); + EXPECT_NEAR(thisZoneSysMoistureDemand.TotalOutputRequired, thisZoneSysMoistureDemand.ZoneMoisturePredictedRate, AcceptableTolerance); + EXPECT_NEAR( + thisZoneSysMoistureDemand.OutputRequiredToHumidifyingSP, thisZoneSysMoistureDemand.ZoneMoisturePredictedHumSPRate, AcceptableTolerance); + EXPECT_NEAR( + thisZoneSysMoistureDemand.OutputRequiredToDehumidifyingSP, thisZoneSysMoistureDemand.ZoneMoisturePredictedDehumSPRate, AcceptableTolerance); // Test 2a: Zone Multiplier (non-list) is greater than 1, list Zone Multiplier is still one - TotOutReq = 1000.0; - OutReqToHumSP = 2000.0; - OutReqToDehumSP = 3000.0; - ZoneMultiplier = 7.0; - ZoneMultiplierList = 1.0; - ReportMoistLoadsZoneMultiplier( - TotOutReq, OutReqToHumSP, OutReqToDehumSP, SingleZoneTotRate, SingleZoneHumRate, SingleZoneDehRate, ZoneMultiplier, ZoneMultiplierList); + thisZone.Multiplier = 7.0; + thisZone.ListMultiplier = 1.0; + thisZoneSysMoistureDemand.reportMoistLoadsZoneMultiplier( + *state, zoneNum, totalOutputRequired, outputRequiredToHumidifyingSP, outputRequiredToDehumidifyingSP); ExpectedResult = 1000.0; - EXPECT_NEAR(ExpectedResult, SingleZoneTotRate, AcceptableTolerance); + EXPECT_NEAR(ExpectedResult, thisZoneSysMoistureDemand.ZoneMoisturePredictedRate, AcceptableTolerance); ExpectedResult = 2000.0; - EXPECT_NEAR(ExpectedResult, SingleZoneHumRate, AcceptableTolerance); + EXPECT_NEAR(ExpectedResult, thisZoneSysMoistureDemand.ZoneMoisturePredictedHumSPRate, AcceptableTolerance); ExpectedResult = 3000.0; - EXPECT_NEAR(ExpectedResult, SingleZoneDehRate, AcceptableTolerance); + EXPECT_NEAR(ExpectedResult, thisZoneSysMoistureDemand.ZoneMoisturePredictedDehumSPRate, AcceptableTolerance); ExpectedResult = 7000.0; - EXPECT_NEAR(TotOutReq, ExpectedResult, AcceptableTolerance); + EXPECT_NEAR(thisZoneSysMoistureDemand.TotalOutputRequired, ExpectedResult, AcceptableTolerance); ExpectedResult = 14000.0; - EXPECT_NEAR(OutReqToHumSP, ExpectedResult, AcceptableTolerance); + EXPECT_NEAR(thisZoneSysMoistureDemand.OutputRequiredToHumidifyingSP, ExpectedResult, AcceptableTolerance); ExpectedResult = 21000.0; - EXPECT_NEAR(OutReqToDehumSP, ExpectedResult, AcceptableTolerance); + EXPECT_NEAR(thisZoneSysMoistureDemand.OutputRequiredToDehumidifyingSP, ExpectedResult, AcceptableTolerance); // Test 2b: list Zone Multiplier is greater than 1, non-list Zone Multiplier is one - TotOutReq = 1000.0; - OutReqToHumSP = 2000.0; - OutReqToDehumSP = 3000.0; - ZoneMultiplier = 1.0; - ZoneMultiplierList = 7.0; - ReportMoistLoadsZoneMultiplier( - TotOutReq, OutReqToHumSP, OutReqToDehumSP, SingleZoneTotRate, SingleZoneHumRate, SingleZoneDehRate, ZoneMultiplier, ZoneMultiplierList); + thisZone.Multiplier = 1.0; + thisZone.ListMultiplier = 7.0; + thisZoneSysMoistureDemand.reportMoistLoadsZoneMultiplier( + *state, zoneNum, totalOutputRequired, outputRequiredToHumidifyingSP, outputRequiredToDehumidifyingSP); ExpectedResult = 1000.0; - EXPECT_NEAR(ExpectedResult, SingleZoneTotRate, AcceptableTolerance); + EXPECT_NEAR(ExpectedResult, thisZoneSysMoistureDemand.ZoneMoisturePredictedRate, AcceptableTolerance); ExpectedResult = 2000.0; - EXPECT_NEAR(ExpectedResult, SingleZoneHumRate, AcceptableTolerance); + EXPECT_NEAR(ExpectedResult, thisZoneSysMoistureDemand.ZoneMoisturePredictedHumSPRate, AcceptableTolerance); ExpectedResult = 3000.0; - EXPECT_NEAR(ExpectedResult, SingleZoneDehRate, AcceptableTolerance); + EXPECT_NEAR(ExpectedResult, thisZoneSysMoistureDemand.ZoneMoisturePredictedDehumSPRate, AcceptableTolerance); ExpectedResult = 7000.0; - EXPECT_NEAR(TotOutReq, ExpectedResult, AcceptableTolerance); + EXPECT_NEAR(thisZoneSysMoistureDemand.TotalOutputRequired, ExpectedResult, AcceptableTolerance); ExpectedResult = 14000.0; - EXPECT_NEAR(OutReqToHumSP, ExpectedResult, AcceptableTolerance); + EXPECT_NEAR(thisZoneSysMoistureDemand.OutputRequiredToHumidifyingSP, ExpectedResult, AcceptableTolerance); ExpectedResult = 21000.0; - EXPECT_NEAR(OutReqToDehumSP, ExpectedResult, AcceptableTolerance); + EXPECT_NEAR(thisZoneSysMoistureDemand.OutputRequiredToDehumidifyingSP, ExpectedResult, AcceptableTolerance); // Test 3: both zone multipliers are greater than 1.0 - TotOutReq = 300.0; - OutReqToHumSP = 150.0; - OutReqToDehumSP = 100.0; - ZoneMultiplier = 2.0; - ZoneMultiplierList = 3.0; - ReportMoistLoadsZoneMultiplier( - TotOutReq, OutReqToHumSP, OutReqToDehumSP, SingleZoneTotRate, SingleZoneHumRate, SingleZoneDehRate, ZoneMultiplier, ZoneMultiplierList); + totalOutputRequired = 300.0; + outputRequiredToHumidifyingSP = 150.0; + outputRequiredToDehumidifyingSP = 100.0; + thisZone.Multiplier = 2.0; + thisZone.ListMultiplier = 3.0; + thisZoneSysMoistureDemand.reportMoistLoadsZoneMultiplier( + *state, zoneNum, totalOutputRequired, outputRequiredToHumidifyingSP, outputRequiredToDehumidifyingSP); ExpectedResult = 300.0; - EXPECT_NEAR(ExpectedResult, SingleZoneTotRate, AcceptableTolerance); + EXPECT_NEAR(ExpectedResult, thisZoneSysMoistureDemand.ZoneMoisturePredictedRate, AcceptableTolerance); ExpectedResult = 150.0; - EXPECT_NEAR(ExpectedResult, SingleZoneHumRate, AcceptableTolerance); + EXPECT_NEAR(ExpectedResult, thisZoneSysMoistureDemand.ZoneMoisturePredictedHumSPRate, AcceptableTolerance); ExpectedResult = 100.0; - EXPECT_NEAR(ExpectedResult, SingleZoneDehRate, AcceptableTolerance); + EXPECT_NEAR(ExpectedResult, thisZoneSysMoistureDemand.ZoneMoisturePredictedDehumSPRate, AcceptableTolerance); ExpectedResult = 1800.0; - EXPECT_NEAR(TotOutReq, ExpectedResult, AcceptableTolerance); + EXPECT_NEAR(thisZoneSysMoistureDemand.TotalOutputRequired, ExpectedResult, AcceptableTolerance); ExpectedResult = 900.0; - EXPECT_NEAR(OutReqToHumSP, ExpectedResult, AcceptableTolerance); + EXPECT_NEAR(thisZoneSysMoistureDemand.OutputRequiredToHumidifyingSP, ExpectedResult, AcceptableTolerance); ExpectedResult = 600.0; - EXPECT_NEAR(OutReqToDehumSP, ExpectedResult, AcceptableTolerance); + EXPECT_NEAR(thisZoneSysMoistureDemand.OutputRequiredToDehumidifyingSP, ExpectedResult, AcceptableTolerance); } TEST_F(EnergyPlusFixture, ReportSensibleLoadsZoneMultiplier_Test) { - Real64 TotOutReq; - Real64 OutReqToHeatSP; - Real64 OutReqToCoolSP; - Real64 SingleZoneTotRate; - Real64 SingleZoneHeatRate; - Real64 SingleZoneCoolRate; - Real64 HeatToSP; - Real64 CoolToSP; - Real64 CorrectionFactor; - Real64 ZoneMultiplier; - Real64 ZoneMultiplierList; + int zoneNum = 1; + state->dataZoneEnergyDemand->ZoneSysEnergyDemand.allocate(zoneNum); + auto &thisZoneSysEnergyDemand = state->dataZoneEnergyDemand->ZoneSysEnergyDemand(zoneNum); + Real64 &SingleZoneTotRate = thisZoneSysEnergyDemand.ZoneSNLoadPredictedRate; + Real64 &SingleZoneHeatRate = thisZoneSysEnergyDemand.ZoneSNLoadPredictedHSPRate; + Real64 &SingleZoneCoolRate = thisZoneSysEnergyDemand.ZoneSNLoadPredictedCSPRate; + state->dataHeatBalFanSys->LoadCorrectionFactor.allocate(zoneNum); + Real64 &CorrectionFactor = state->dataHeatBalFanSys->LoadCorrectionFactor(zoneNum); + state->dataHeatBal->Zone.allocate(zoneNum); + auto &thisZone = state->dataHeatBal->Zone(zoneNum); Real64 ExpectedResult; Real64 AcceptableTolerance = 0.00001; // Test 1: Zone Multipliers and Load Correction Factor are all unity (1.0). So, single zone loads should be the same as total loads - TotOutReq = 1000.0; - OutReqToHeatSP = 0.0; - OutReqToCoolSP = 0.0; - HeatToSP = 2000.0; - CoolToSP = 3000.0; + thisZoneSysEnergyDemand.TotalOutputRequired = 0.0; + thisZoneSysEnergyDemand.OutputRequiredToHeatingSP = 0.0; + thisZoneSysEnergyDemand.OutputRequiredToCoolingSP = 0.0; + Real64 totalOutputRequired = 1000.0; + Real64 HeatToSP = 2000.0; + Real64 CoolToSP = 3000.0; CorrectionFactor = 1.0; - ZoneMultiplier = 1.0; - ZoneMultiplierList = 1.0; - ReportSensibleLoadsZoneMultiplier(TotOutReq, - OutReqToHeatSP, - OutReqToCoolSP, - SingleZoneTotRate, - SingleZoneHeatRate, - SingleZoneCoolRate, - HeatToSP, - CoolToSP, - CorrectionFactor, - ZoneMultiplier, - ZoneMultiplierList); - EXPECT_NEAR(TotOutReq, SingleZoneTotRate, AcceptableTolerance); - EXPECT_NEAR(OutReqToHeatSP, SingleZoneHeatRate, AcceptableTolerance); - EXPECT_NEAR(OutReqToCoolSP, SingleZoneCoolRate, AcceptableTolerance); + thisZone.Multiplier = 1.0; + thisZone.ListMultiplier = 1.0; + thisZoneSysEnergyDemand.reportSensibleLoadsZoneMultiplier(*state, zoneNum, totalOutputRequired, HeatToSP, CoolToSP); + EXPECT_NEAR(thisZoneSysEnergyDemand.TotalOutputRequired, SingleZoneTotRate, AcceptableTolerance); + EXPECT_NEAR(thisZoneSysEnergyDemand.OutputRequiredToHeatingSP, SingleZoneHeatRate, AcceptableTolerance); + EXPECT_NEAR(thisZoneSysEnergyDemand.OutputRequiredToCoolingSP, SingleZoneCoolRate, AcceptableTolerance); // Test 2a: Zone Multiplier (non-list) is greater than 1, list Zone Multiplier and Load Correction are still one - TotOutReq = 1000.0; - OutReqToHeatSP = 0.0; - OutReqToCoolSP = 0.0; + thisZoneSysEnergyDemand.TotalOutputRequired = 0.0; + thisZoneSysEnergyDemand.OutputRequiredToHeatingSP = 0.0; + thisZoneSysEnergyDemand.OutputRequiredToCoolingSP = 0.0; + totalOutputRequired = 1000.0; HeatToSP = 2000.0; CoolToSP = 3000.0; CorrectionFactor = 1.0; - ZoneMultiplier = 4.0; - ZoneMultiplierList = 1.0; - ReportSensibleLoadsZoneMultiplier(TotOutReq, - OutReqToHeatSP, - OutReqToCoolSP, - SingleZoneTotRate, - SingleZoneHeatRate, - SingleZoneCoolRate, - HeatToSP, - CoolToSP, - CorrectionFactor, - ZoneMultiplier, - ZoneMultiplierList); + thisZone.Multiplier = 4.0; + thisZone.ListMultiplier = 1.0; + thisZoneSysEnergyDemand.reportSensibleLoadsZoneMultiplier(*state, zoneNum, totalOutputRequired, HeatToSP, CoolToSP); ExpectedResult = 1000.0; EXPECT_NEAR(ExpectedResult, SingleZoneTotRate, AcceptableTolerance); ExpectedResult = 2000.0; @@ -1660,32 +1574,23 @@ TEST_F(EnergyPlusFixture, ReportSensibleLoadsZoneMultiplier_Test) ExpectedResult = 3000.0; EXPECT_NEAR(ExpectedResult, SingleZoneCoolRate, AcceptableTolerance); ExpectedResult = 4000.0; - EXPECT_NEAR(TotOutReq, ExpectedResult, AcceptableTolerance); + EXPECT_NEAR(thisZoneSysEnergyDemand.TotalOutputRequired, ExpectedResult, AcceptableTolerance); ExpectedResult = 8000.0; - EXPECT_NEAR(OutReqToHeatSP, ExpectedResult, AcceptableTolerance); + EXPECT_NEAR(thisZoneSysEnergyDemand.OutputRequiredToHeatingSP, ExpectedResult, AcceptableTolerance); ExpectedResult = 12000.0; - EXPECT_NEAR(OutReqToCoolSP, ExpectedResult, AcceptableTolerance); + EXPECT_NEAR(thisZoneSysEnergyDemand.OutputRequiredToCoolingSP, ExpectedResult, AcceptableTolerance); // Test 2b: list Zone Multiplier is greater than 1, non-list Zone Multiplier and Load Correction are still one - TotOutReq = 1000.0; - OutReqToHeatSP = 0.0; - OutReqToCoolSP = 0.0; + thisZoneSysEnergyDemand.TotalOutputRequired = 0.0; + thisZoneSysEnergyDemand.OutputRequiredToHeatingSP = 0.0; + thisZoneSysEnergyDemand.OutputRequiredToCoolingSP = 0.0; + totalOutputRequired = 1000.0; HeatToSP = 2000.0; CoolToSP = 3000.0; CorrectionFactor = 1.0; - ZoneMultiplier = 1.0; - ZoneMultiplierList = 5.0; - ReportSensibleLoadsZoneMultiplier(TotOutReq, - OutReqToHeatSP, - OutReqToCoolSP, - SingleZoneTotRate, - SingleZoneHeatRate, - SingleZoneCoolRate, - HeatToSP, - CoolToSP, - CorrectionFactor, - ZoneMultiplier, - ZoneMultiplierList); + thisZone.Multiplier = 1.0; + thisZone.ListMultiplier = 5.0; + thisZoneSysEnergyDemand.reportSensibleLoadsZoneMultiplier(*state, zoneNum, totalOutputRequired, HeatToSP, CoolToSP); ExpectedResult = 1000.0; EXPECT_NEAR(ExpectedResult, SingleZoneTotRate, AcceptableTolerance); ExpectedResult = 2000.0; @@ -1693,32 +1598,23 @@ TEST_F(EnergyPlusFixture, ReportSensibleLoadsZoneMultiplier_Test) ExpectedResult = 3000.0; EXPECT_NEAR(ExpectedResult, SingleZoneCoolRate, AcceptableTolerance); ExpectedResult = 5000.0; - EXPECT_NEAR(TotOutReq, ExpectedResult, AcceptableTolerance); + EXPECT_NEAR(thisZoneSysEnergyDemand.TotalOutputRequired, ExpectedResult, AcceptableTolerance); ExpectedResult = 10000.0; - EXPECT_NEAR(OutReqToHeatSP, ExpectedResult, AcceptableTolerance); + EXPECT_NEAR(thisZoneSysEnergyDemand.OutputRequiredToHeatingSP, ExpectedResult, AcceptableTolerance); ExpectedResult = 15000.0; - EXPECT_NEAR(OutReqToCoolSP, ExpectedResult, AcceptableTolerance); + EXPECT_NEAR(thisZoneSysEnergyDemand.OutputRequiredToCoolingSP, ExpectedResult, AcceptableTolerance); // Test 2c: list Zone Multiplier and Zone Multiplier are unity, Load Correction is not equal to 1.0 - TotOutReq = 1000.0; - OutReqToHeatSP = 0.0; - OutReqToCoolSP = 0.0; + thisZoneSysEnergyDemand.TotalOutputRequired = 0.0; + thisZoneSysEnergyDemand.OutputRequiredToHeatingSP = 0.0; + thisZoneSysEnergyDemand.OutputRequiredToCoolingSP = 0.0; + totalOutputRequired = 1000.0; HeatToSP = 2000.0; CoolToSP = 3000.0; CorrectionFactor = 1.1; - ZoneMultiplier = 1.0; - ZoneMultiplierList = 1.0; - ReportSensibleLoadsZoneMultiplier(TotOutReq, - OutReqToHeatSP, - OutReqToCoolSP, - SingleZoneTotRate, - SingleZoneHeatRate, - SingleZoneCoolRate, - HeatToSP, - CoolToSP, - CorrectionFactor, - ZoneMultiplier, - ZoneMultiplierList); + thisZone.Multiplier = 1.0; + thisZone.ListMultiplier = 1.0; + thisZoneSysEnergyDemand.reportSensibleLoadsZoneMultiplier(*state, zoneNum, totalOutputRequired, HeatToSP, CoolToSP); ExpectedResult = 1100.0; EXPECT_NEAR(ExpectedResult, SingleZoneTotRate, AcceptableTolerance); ExpectedResult = 2200.0; @@ -1726,32 +1622,23 @@ TEST_F(EnergyPlusFixture, ReportSensibleLoadsZoneMultiplier_Test) ExpectedResult = 3300.0; EXPECT_NEAR(ExpectedResult, SingleZoneCoolRate, AcceptableTolerance); ExpectedResult = 1100.0; - EXPECT_NEAR(TotOutReq, ExpectedResult, AcceptableTolerance); + EXPECT_NEAR(thisZoneSysEnergyDemand.TotalOutputRequired, ExpectedResult, AcceptableTolerance); ExpectedResult = 2200.0; - EXPECT_NEAR(OutReqToHeatSP, ExpectedResult, AcceptableTolerance); + EXPECT_NEAR(thisZoneSysEnergyDemand.OutputRequiredToHeatingSP, ExpectedResult, AcceptableTolerance); ExpectedResult = 3300.0; - EXPECT_NEAR(OutReqToCoolSP, ExpectedResult, AcceptableTolerance); + EXPECT_NEAR(thisZoneSysEnergyDemand.OutputRequiredToCoolingSP, ExpectedResult, AcceptableTolerance); // Test 3: none of the multipliers are unity - TotOutReq = 1000.0; - OutReqToHeatSP = 0.0; - OutReqToCoolSP = 0.0; + thisZoneSysEnergyDemand.TotalOutputRequired = 0.0; + thisZoneSysEnergyDemand.OutputRequiredToHeatingSP = 0.0; + thisZoneSysEnergyDemand.OutputRequiredToCoolingSP = 0.0; + totalOutputRequired = 1000.0; HeatToSP = 2000.0; CoolToSP = 3000.0; CorrectionFactor = 1.2; - ZoneMultiplier = 2.0; - ZoneMultiplierList = 1.5; - ReportSensibleLoadsZoneMultiplier(TotOutReq, - OutReqToHeatSP, - OutReqToCoolSP, - SingleZoneTotRate, - SingleZoneHeatRate, - SingleZoneCoolRate, - HeatToSP, - CoolToSP, - CorrectionFactor, - ZoneMultiplier, - ZoneMultiplierList); + thisZone.Multiplier = 1.0; + thisZone.ListMultiplier = 3.0; + thisZoneSysEnergyDemand.reportSensibleLoadsZoneMultiplier(*state, zoneNum, totalOutputRequired, HeatToSP, CoolToSP); ExpectedResult = 1200.0; EXPECT_NEAR(ExpectedResult, SingleZoneTotRate, AcceptableTolerance); ExpectedResult = 2400.0; @@ -1759,11 +1646,11 @@ TEST_F(EnergyPlusFixture, ReportSensibleLoadsZoneMultiplier_Test) ExpectedResult = 3600.0; EXPECT_NEAR(ExpectedResult, SingleZoneCoolRate, AcceptableTolerance); ExpectedResult = 3600.0; - EXPECT_NEAR(TotOutReq, ExpectedResult, AcceptableTolerance); + EXPECT_NEAR(thisZoneSysEnergyDemand.TotalOutputRequired, ExpectedResult, AcceptableTolerance); ExpectedResult = 7200.0; - EXPECT_NEAR(OutReqToHeatSP, ExpectedResult, AcceptableTolerance); + EXPECT_NEAR(thisZoneSysEnergyDemand.OutputRequiredToHeatingSP, ExpectedResult, AcceptableTolerance); ExpectedResult = 10800.0; - EXPECT_NEAR(OutReqToCoolSP, ExpectedResult, AcceptableTolerance); + EXPECT_NEAR(thisZoneSysEnergyDemand.OutputRequiredToCoolingSP, ExpectedResult, AcceptableTolerance); } TEST_F(EnergyPlusFixture, DownInterpolate4HistoryValues_Test)