@@ -587,7 +587,7 @@ void GetZoneEquipmentData(EnergyPlusData &state)
587
587
continue ;
588
588
}
589
589
590
- processZoneReturnMixerInput (state, CurrentModuleObject, zoneNum, objectSchemaProps, objectFields, thisZretMixer );
590
+ processZoneReturnMixerInput (state, CurrentModuleObject, zoneNum, objectSchemaProps, objectFields, zeqRetNum );
591
591
}
592
592
} // end loop over zone return mixers
593
593
@@ -1326,20 +1326,20 @@ void processZoneEquipMixerInput(EnergyPlusData &state,
1326
1326
static constexpr std::string_view RoutineName (" processZoneEquipMixerInput: " ); // include trailing blank space
1327
1327
auto &ip = state.dataInputProcessing ->inputProcessor ;
1328
1328
bool objectIsParent = true ;
1329
- thisZeqMixer.zoneEquipInletNodeNum = GetOnlySingleNode (state,
1330
- ip->getAlphaFieldValue (objectFields, objectSchemaProps, " zone_equipment_inlet_node_name" ),
1331
- state.dataZoneEquip ->GetZoneEquipmentDataErrorsFound ,
1332
- thisZeqMixer.spaceEquipType ,
1333
- thisZeqMixer.Name ,
1334
- DataLoopNode::NodeFluidType::Air,
1335
- DataLoopNode::ConnectionType::Outlet,
1336
- NodeInputManager::CompFluidStream::Primary,
1337
- objectIsParent);
1329
+ thisZeqMixer.outletNodeNum = GetOnlySingleNode (state,
1330
+ ip->getAlphaFieldValue (objectFields, objectSchemaProps, " zone_equipment_inlet_node_name" ),
1331
+ state.dataZoneEquip ->GetZoneEquipmentDataErrorsFound ,
1332
+ thisZeqMixer.spaceEquipType ,
1333
+ thisZeqMixer.Name ,
1334
+ DataLoopNode::NodeFluidType::Air,
1335
+ DataLoopNode::ConnectionType::Outlet,
1336
+ NodeInputManager::CompFluidStream::Primary,
1337
+ objectIsParent);
1338
1338
// Check zone exhaust nodes
1339
1339
bool found = false ;
1340
1340
auto &thisZoneEquipConfig = state.dataZoneEquip ->ZoneEquipConfig (zoneNum);
1341
1341
for (int exhNodeNum : thisZoneEquipConfig.ExhaustNode ) {
1342
- if (thisZeqMixer.zoneEquipInletNodeNum == exhNodeNum) {
1342
+ if (thisZeqMixer.outletNodeNum == exhNodeNum) {
1343
1343
found = true ;
1344
1344
break ;
1345
1345
}
@@ -1348,7 +1348,7 @@ void processZoneEquipMixerInput(EnergyPlusData &state,
1348
1348
ShowSevereError (state, format (" {}{}={}" , RoutineName, zeqMixerModuleObject, thisZeqMixer.Name ));
1349
1349
ShowContinueError (state,
1350
1350
format (" Zone Equipment Inlet Node Name={} is not an exhaust node for ZoneHVAC:EquipmentConnections={}." ,
1351
- state.dataLoopNodes ->NodeID (thisZeqMixer.zoneEquipInletNodeNum ),
1351
+ state.dataLoopNodes ->NodeID (thisZeqMixer.outletNodeNum ),
1352
1352
thisZoneEquipConfig.ZoneName ));
1353
1353
state.dataZoneEquip ->GetZoneEquipmentDataErrorsFound = true ;
1354
1354
}
@@ -1410,35 +1410,45 @@ void processZoneReturnMixerInput(EnergyPlusData &state,
1410
1410
int const zoneNum,
1411
1411
InputProcessor::json const objectSchemaProps,
1412
1412
InputProcessor::json const objectFields,
1413
- DataZoneEquipment::ZoneReturnMixer &thisZretMixer )
1413
+ int mixerIndex )
1414
1414
1415
1415
{
1416
1416
static constexpr std::string_view RoutineName (" processZoneReturnMixerInput: " ); // include trailing blank space
1417
1417
auto &ip = state.dataInputProcessing ->inputProcessor ;
1418
1418
bool objectIsParent = true ;
1419
- thisZretMixer.zoneReturnNodeNum = GetOnlySingleNode (state,
1420
- ip->getAlphaFieldValue (objectFields, objectSchemaProps, " zone_return_air_node_name" ),
1421
- state.dataZoneEquip ->GetZoneEquipmentDataErrorsFound ,
1422
- thisZretMixer.spaceEquipType ,
1423
- thisZretMixer.Name ,
1424
- DataLoopNode::NodeFluidType::Air,
1425
- DataLoopNode::ConnectionType::Outlet,
1426
- NodeInputManager::CompFluidStream::Primary,
1427
- objectIsParent);
1419
+ auto &thisZretMixer = state.dataZoneEquip ->zoneReturnMixer [mixerIndex];
1420
+ thisZretMixer.outletNodeNum = GetOnlySingleNode (state,
1421
+ ip->getAlphaFieldValue (objectFields, objectSchemaProps, " zone_return_air_node_name" ),
1422
+ state.dataZoneEquip ->GetZoneEquipmentDataErrorsFound ,
1423
+ thisZretMixer.spaceEquipType ,
1424
+ thisZretMixer.Name ,
1425
+ DataLoopNode::NodeFluidType::Air,
1426
+ DataLoopNode::ConnectionType::Outlet,
1427
+ NodeInputManager::CompFluidStream::Primary,
1428
+ objectIsParent);
1428
1429
// Check zone return nodes
1429
1430
bool found = false ;
1430
1431
auto &thisZoneEquipConfig = state.dataZoneEquip ->ZoneEquipConfig (zoneNum);
1432
+ thisZoneEquipConfig.returnNodeSpaceMixerIndex .allocate (thisZoneEquipConfig.NumReturnNodes );
1433
+ for (int &mixIndex : thisZoneEquipConfig.returnNodeSpaceMixerIndex ) {
1434
+ mixIndex = -1 ;
1435
+ }
1436
+
1437
+ int nodeCounter = 0 ;
1431
1438
for (int retNodeNum : thisZoneEquipConfig.ReturnNode ) {
1432
- if (thisZretMixer.zoneReturnNodeNum == retNodeNum) {
1439
+ ++nodeCounter;
1440
+ if (thisZretMixer.outletNodeNum == retNodeNum) {
1433
1441
found = true ;
1442
+ // Zone return node is fed by a space return mixer
1443
+ thisZoneEquipConfig.returnNodeSpaceMixerIndex (nodeCounter) = mixerIndex;
1434
1444
break ;
1435
1445
}
1436
1446
}
1437
1447
if (!found) {
1438
1448
ShowSevereError (state, format (" {}{}={}" , RoutineName, zeqMixerModuleObject, thisZretMixer.Name ));
1439
1449
ShowContinueError (state,
1440
1450
format (" Zone Equipment Return Air Node Name={} is not a return air node for ZoneHVAC:EquipmentConnections={}." ,
1441
- state.dataLoopNodes ->NodeID (thisZretMixer.zoneReturnNodeNum ),
1451
+ state.dataLoopNodes ->NodeID (thisZretMixer.outletNodeNum ),
1442
1452
thisZoneEquipConfig.ZoneName ));
1443
1453
state.dataZoneEquip ->GetZoneEquipmentDataErrorsFound = true ;
1444
1454
}
@@ -1923,17 +1933,17 @@ void ZoneEquipmentSplitterMixer::size(EnergyPlusData &state)
1923
1933
}
1924
1934
}
1925
1935
1926
- void ZoneEquipmentMixer ::setOutletConditions (EnergyPlusData &state)
1936
+ void ZoneMixer ::setOutletConditions (EnergyPlusData &state)
1927
1937
{
1928
- if (this ->zoneEquipInletNodeNum == 0 ) return ;
1938
+ if (this ->outletNodeNum == 0 ) return ;
1929
1939
1930
1940
Real64 sumEnthalpy = 0.0 ;
1931
1941
Real64 sumHumRat = 0.0 ;
1932
1942
Real64 sumCO2 = 0.0 ;
1933
1943
Real64 sumGenContam = 0.0 ;
1934
1944
Real64 sumPressure = 0.0 ;
1935
1945
Real64 sumFractions = 0.0 ;
1936
- auto &equipInletNode = state.dataLoopNodes ->Node (this ->zoneEquipInletNodeNum );
1946
+ auto &outletNode = state.dataLoopNodes ->Node (this ->outletNodeNum );
1937
1947
for (auto &mixerSpace : this ->spaces ) {
1938
1948
auto &spaceOutletNode = state.dataLoopNodes ->Node (mixerSpace.spaceNodeNum );
1939
1949
sumEnthalpy += spaceOutletNode.Enthalpy * mixerSpace.fraction ;
@@ -1947,25 +1957,47 @@ void ZoneEquipmentMixer::setOutletConditions(EnergyPlusData &state)
1947
1957
sumPressure += spaceOutletNode.Press * mixerSpace.fraction ;
1948
1958
sumFractions += mixerSpace.fraction ;
1949
1959
}
1950
- equipInletNode.Enthalpy = sumEnthalpy / sumFractions;
1951
- equipInletNode.HumRat = sumHumRat / sumFractions;
1952
- if (state.dataContaminantBalance ->Contaminant .CO2Simulation ) {
1953
- equipInletNode.CO2 = sumCO2 / sumFractions;
1954
- }
1955
- if (state.dataContaminantBalance ->Contaminant .GenericContamSimulation ) {
1956
- equipInletNode.GenContam = sumGenContam / sumFractions;
1957
- }
1958
- equipInletNode.Press = sumPressure / sumFractions;
1959
1960
1960
- // Use Enthalpy and humidity ratio to get outlet temperature from psych chart
1961
- equipInletNode.Temp = Psychrometrics::PsyTdbFnHW (equipInletNode.Enthalpy , equipInletNode.HumRat );
1961
+ // For SpaceHVAC:ZoneReturnMixer, the fractions are dynamic and could be zero if there is no flow
1962
+ if (sumFractions > 0 ) {
1963
+ outletNode.Enthalpy = sumEnthalpy / sumFractions;
1964
+ outletNode.HumRat = sumHumRat / sumFractions;
1965
+ if (state.dataContaminantBalance ->Contaminant .CO2Simulation ) {
1966
+ outletNode.CO2 = sumCO2 / sumFractions;
1967
+ }
1968
+ if (state.dataContaminantBalance ->Contaminant .GenericContamSimulation ) {
1969
+ outletNode.GenContam = sumGenContam / sumFractions;
1970
+ }
1971
+ outletNode.Press = sumPressure / sumFractions;
1972
+
1973
+ // Use Enthalpy and humidity ratio to get outlet temperature from psych chart
1974
+ outletNode.Temp = Psychrometrics::PsyTdbFnHW (outletNode.Enthalpy , outletNode.HumRat );
1975
+ }
1962
1976
}
1963
1977
1978
+ void ZoneReturnMixer::setInletConditions (EnergyPlusData &state)
1979
+ {
1980
+ for (auto &mixerSpace : this ->spaces ) {
1981
+ auto &spaceOutletNode = state.dataLoopNodes ->Node (mixerSpace.spaceNodeNum );
1982
+ int spaceZoneNodeNum = state.dataZoneEquip ->spaceEquipConfig (mixerSpace.spaceIndex ).ZoneNode ;
1983
+ auto &spaceNode = state.dataLoopNodes ->Node (spaceZoneNodeNum);
1984
+ spaceOutletNode.Temp = spaceNode.Temp ;
1985
+ spaceOutletNode.HumRat = spaceNode.HumRat ;
1986
+ spaceOutletNode.Enthalpy = spaceNode.Enthalpy ;
1987
+ spaceOutletNode.Press = spaceNode.Press ;
1988
+ if (state.dataContaminantBalance ->Contaminant .CO2Simulation ) {
1989
+ spaceOutletNode.CO2 = spaceNode.CO2 ;
1990
+ }
1991
+ if (state.dataContaminantBalance ->Contaminant .GenericContamSimulation ) {
1992
+ spaceOutletNode.GenContam = spaceNode.GenContam ;
1993
+ }
1994
+ }
1995
+ }
1964
1996
void ZoneEquipmentMixer::setInletFlows (EnergyPlusData &state)
1965
1997
{
1966
- if (this ->zoneEquipInletNodeNum == 0 ) return ;
1998
+ if (this ->outletNodeNum == 0 ) return ;
1967
1999
1968
- auto &equipInletNode = state.dataLoopNodes ->Node (this ->zoneEquipInletNodeNum );
2000
+ auto &equipInletNode = state.dataLoopNodes ->Node (this ->outletNodeNum );
1969
2001
for (auto &mixerSpace : this ->spaces ) {
1970
2002
auto &spaceOutletNode = state.dataLoopNodes ->Node (mixerSpace.spaceNodeNum );
1971
2003
spaceOutletNode.MassFlowRate = equipInletNode.MassFlowRate * mixerSpace.fraction ;
@@ -1974,6 +2006,35 @@ void ZoneEquipmentMixer::setInletFlows(EnergyPlusData &state)
1974
2006
}
1975
2007
}
1976
2008
2009
+ void ZoneReturnMixer::setInletFlows (EnergyPlusData &state)
2010
+ {
2011
+ if (this ->outletNodeNum == 0 ) return ;
2012
+ auto &outletNode = state.dataLoopNodes ->Node (this ->outletNodeNum );
2013
+
2014
+ Real64 sumMixerInletMassFlow = 0 ;
2015
+ for (auto const &mixerSpace : this ->spaces ) {
2016
+ // calc return flows for spaces feeding this mixer
2017
+ auto &spaceEquipConfig = state.dataZoneEquip ->spaceEquipConfig (mixerSpace.spaceIndex );
2018
+ Real64 outletMassFlowRate = outletNode.MassFlowRate ; // calcReturnFlows might adjust this parameter value, so make a copy here
2019
+ Real64 spaceReturnFlow = 0.0 ;
2020
+ spaceEquipConfig.calcReturnFlows (state, outletMassFlowRate, spaceReturnFlow);
2021
+ sumMixerInletMassFlow += spaceReturnFlow;
2022
+ }
2023
+
2024
+ for (auto &mixerSpace : this ->spaces ) {
2025
+ auto &spaceOutletNode = state.dataLoopNodes ->Node (mixerSpace.spaceNodeNum );
2026
+ // For return mixer, fraction is calculated every time step, not a user input
2027
+ if (sumMixerInletMassFlow > 0.0 ) {
2028
+ mixerSpace.fraction = spaceOutletNode.MassFlowRate / sumMixerInletMassFlow;
2029
+ } else {
2030
+ mixerSpace.fraction = 0.0 ;
2031
+ }
2032
+ spaceOutletNode.MassFlowRate = outletNode.MassFlowRate * mixerSpace.fraction ;
2033
+ spaceOutletNode.MassFlowRateMaxAvail = outletNode.MassFlowRateMaxAvail * mixerSpace.fraction ;
2034
+ spaceOutletNode.MassFlowRateMinAvail = outletNode.MassFlowRateMinAvail * mixerSpace.fraction ;
2035
+ }
2036
+ }
2037
+
1977
2038
void ZoneEquipmentSplitter::adjustLoads (EnergyPlusData &state, int zoneNum, int equipTypeNum)
1978
2039
{
1979
2040
auto &thisZoneEnergyDemand = state.dataZoneEnergyDemand ->ZoneSysEnergyDemand (zoneNum);
0 commit comments