Skip to content

Commit cae21a5

Browse files
committed
Port in first check of distribution
1 parent 002d57b commit cae21a5

File tree

4 files changed

+77
-39
lines changed

4 files changed

+77
-39
lines changed

src/EnergyPlus/AirflowNetwork/include/AirflowNetwork/Elements.hpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -847,11 +847,11 @@ namespace AirflowNetwork {
847847
std::string node_name; // EnergyPlus node name
848848
std::string EPlusType; // EnergyPlus node type
849849
Real64 Height; // Nodal height
850-
int EPlusNodeNum; // EPlus node number
850+
int node_number; // EPlus node number
851851
int AirLoopNum; // AirLoop number
852852

853853
// Default Constructor
854-
DisSysNodeProp() : Height(0.0), EPlusNodeNum(0), AirLoopNum(0)
854+
DisSysNodeProp() : Height(0.0), node_number(0), AirLoopNum(0)
855855
{
856856
}
857857
};
@@ -1285,10 +1285,10 @@ namespace AirflowNetwork {
12851285
{
12861286
// Members
12871287
std::string Name; // Provide a unique node name
1288-
//std::string node_type_string; // Provide node type "External", "Thermal Zone" or "Other"
1289-
//std::string node_name; // EnergyPlus node name
1288+
// std::string node_type_string; // Provide node type "External", "Thermal Zone" or "Other"
1289+
// std::string node_name; // EnergyPlus node name
12901290
Real64 NodeHeight; // Node height [m]
1291-
int NodeNum; // Node number
1291+
// int node_number; // Node number
12921292
int NodeTypeNum; // Node type with integer number, 0: Calculated, 1: Given pressure;
12931293
// std::string zone_name; // EnergyPlus node name
12941294
int EPlusZoneNum; // E+ zone number
@@ -1302,7 +1302,7 @@ namespace AirflowNetwork {
13021302

13031303
// Default Constructor
13041304
AirflowNetworkNodeProp()
1305-
: NodeHeight(0.0), NodeNum(0), NodeTypeNum(0), EPlusZoneNum(0), EPlusNodeNum(0), ExtNodeNum(0), OutAirNodeNum(0),
1305+
: NodeHeight(0.0), /*node_number(0),*/ NodeTypeNum(0), EPlusZoneNum(0), EPlusNodeNum(0), ExtNodeNum(0), OutAirNodeNum(0),
13061306
EPlusTypeNum(NodeType::Unknown), RAFNNodeNum(0), NumOfLinks(0), AirLoopNum(0)
13071307
{
13081308
}

src/EnergyPlus/AirflowNetwork/include/AirflowNetwork/Solver.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,8 @@ namespace AirflowNetwork {
307307
Real64 &OpenFactor // Window or door opening factor (used to calculate airflow)
308308
);
309309
void assign_fan_airloop();
310-
void validate_distribution();
310+
bool validate_network();
311+
void finalize_distribution();
311312
void validate_fan_flowrate(); // Catch a fan flow rate from EPlus input file and add a flag for VAV terminal damper
312313
void validate_exhaust_fan_input();
313314
void hybrid_ventilation_control();
@@ -371,6 +372,7 @@ namespace AirflowNetwork {
371372
Array1D<Real64> LoopOnOffFanRunTimeFraction;
372373
Array1D<bool> LoopOnOffFlag;
373374

375+
bool distribution_is_final = false;
374376
bool ValidateExhaustFanInputOneTimeFlag = true;
375377
bool initializeOneTimeFlag = true;
376378
bool initializeMyEnvrnFlag = true;
@@ -595,6 +597,7 @@ namespace AirflowNetwork {
595597
LoopOnOffFanRunTimeFraction.deallocate();
596598
LoopOnOffFlag.deallocate();
597599
UniqueAirflowNetworkSurfaceName.clear();
600+
distribution_is_final = false;
598601
ValidateExhaustFanInputOneTimeFlag = true;
599602
initializeOneTimeFlag = true;
600603
initializeMyEnvrnFlag = true;

src/EnergyPlus/AirflowNetwork/src/Solver.cpp

Lines changed: 57 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ namespace AirflowNetwork {
287287

288288
if (AirflowNetworkFanActivated && distribution_simulated) {
289289
if (ValidateDistributionSystemFlag) {
290-
validate_distribution();
290+
finalize_distribution();
291291
validate_fan_flowrate();
292292
ValidateDistributionSystemFlag = false;
293293
if (simulation_control.autosize_ducts) {
@@ -3923,7 +3923,7 @@ namespace AirflowNetwork {
39233923
DisSysNodeData(i).node_name = Alphas(2); // Name of associated EnergyPlus node
39243924
DisSysNodeData(i).EPlusType = Alphas(3); // Name of associated EnergyPlus type
39253925
DisSysNodeData(i).Height = Numbers(1); // Nodal height
3926-
DisSysNodeData(i).EPlusNodeNum = 0; // EPlus node number
3926+
DisSysNodeData(i).node_number = 0; // EPlus node number
39273927
// verify EnergyPlus object type
39283928
if (Util::SameString(Alphas(3), "AirLoopHVAC:ZoneMixer") || Util::SameString(Alphas(3), "AirLoopHVAC:ZoneSplitter") ||
39293929
Util::SameString(Alphas(3), "AirLoopHVAC:OutdoorAirSystem") || Util::SameString(Alphas(3), "OAMixerOutdoorAirStreamNode") ||
@@ -4261,7 +4261,7 @@ namespace AirflowNetwork {
42614261
AirflowNetworkNodeData(i).NodeTypeNum = 0;
42624262
AirflowNetworkNodeData(i).EPlusZoneNum = 0;
42634263
AirflowNetworkNodeData(i).NodeHeight = DisSysNodeData(i - NumOfNodesMultiZone).Height;
4264-
AirflowNetworkNodeData(i).EPlusNodeNum = DisSysNodeData(i - NumOfNodesMultiZone).EPlusNodeNum;
4264+
AirflowNetworkNodeData(i).EPlusNodeNum = DisSysNodeData(i - NumOfNodesMultiZone).node_number;
42654265
// Get mixer information
42664266
if (Util::SameString(DisSysNodeData(i - NumOfNodesMultiZone).EPlusType, "AirLoopHVAC:ZoneMixer")) {
42674267
AirflowNetworkNodeData(i).EPlusTypeNum = NodeType::MIX;
@@ -9992,17 +9992,19 @@ namespace AirflowNetwork {
99929992
OpenFactorMult = 1.0;
99939993
} else if (DelEnthal >= UpperValInOutEnthalDiff) {
99949994
OpenFactorMult = LimValVentOpenFacMult;
9995-
} else {
9996-
OpenFactorMult =
9997-
LimValVentOpenFacMult + ((UpperValInOutEnthalDiff - DelEnthal) / (UpperValInOutEnthalDiff - LowerValInOutEnthalDiff)) *
9998-
(1 - LimValVentOpenFacMult);
9995+
}
9996+
else {
9997+
OpenFactorMult =
9998+
LimValVentOpenFacMult + ((UpperValInOutEnthalDiff - DelEnthal) / (UpperValInOutEnthalDiff - LowerValInOutEnthalDiff)) *
9999+
(1 - LimValVentOpenFacMult);
999910000
}
1000010001
OpenFactor *= OpenFactorMult;
1000110002
m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = OpenFactorMult;
1000210003
}
10003-
} else {
10004-
OpenFactor = 0.0;
10005-
m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = -1.0;
10004+
}
10005+
else {
10006+
OpenFactor = 0.0;
10007+
m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = -1.0;
1000610008
}
1000710009
}
1000810010

@@ -10022,13 +10024,16 @@ namespace AirflowNetwork {
1002210024
m_state.dataThermalComforts->ThermalComfortData(PeopleInd).TComfASH55) {
1002310025
OpenFactor = MultizoneSurfaceData(i).Factor;
1002410026
m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = 1.0;
10025-
} else {
10027+
}
10028+
else {
1002610029
OpenFactor = 0.0;
1002710030
}
10028-
} else {
10031+
}
10032+
else {
1002910033
OpenFactor = 0.0;
1003010034
}
10031-
} else {
10035+
}
10036+
else {
1003210037
OpenFactor = 0.0;
1003310038
}
1003410039
}
@@ -10041,13 +10046,16 @@ namespace AirflowNetwork {
1004110046
m_state.dataThermalComforts->ThermalComfortData(PeopleInd).TComfCEN15251) {
1004210047
OpenFactor = MultizoneSurfaceData(i).Factor;
1004310048
m_state.dataSurface->SurfWinVentingOpenFactorMultRep(SurfNum) = 1.0;
10044-
} else {
10049+
}
10050+
else {
1004510051
OpenFactor = 0.0;
1004610052
}
10047-
} else {
10053+
}
10054+
else {
1004810055
OpenFactor = 0.0;
1004910056
}
10050-
} else {
10057+
}
10058+
else {
1005110059
OpenFactor = 0.0;
1005210060
}
1005310061
}
@@ -10078,7 +10086,26 @@ namespace AirflowNetwork {
1007810086
}
1007910087
}
1008010088

10081-
void Solver::validate_distribution()
10089+
bool Solver::validate_network()
10090+
{
10091+
bool result = true;
10092+
// Technically, the nodes could be verified at input time with a bunch of string comparisons on the names,
10093+
// but this will likely be faster and should get the same result
10094+
std::vector<int> nodes_already_in_use;
10095+
for (auto& node : DisSysNodeData) {
10096+
if (node.node_number)
10097+
if (std::find(nodes_already_in_use.begin(), nodes_already_in_use.end(), node.node_number) == nodes_already_in_use.end()) {
10098+
// Node number already in use
10099+
ShowWarningError(m_state, format("validate_network: Node \"{}\" (node number {}) is used more than once as an AirflowNetwork distribution node, verify that this matches the modeling intent", node.node_name, node.node_number));
10100+
result = false;
10101+
} else {
10102+
nodes_already_in_use.push_back(node.node_number);
10103+
}
10104+
}
10105+
return result;
10106+
}
10107+
10108+
void Solver::finalize_distribution()
1008210109
{
1008310110

1008410111
// SUBROUTINE INFORMATION:
@@ -10088,9 +10115,14 @@ namespace AirflowNetwork {
1008810115
// RE-ENGINEERED na
1008910116

1009010117
// PURPOSE OF THIS SUBROUTINE:
10091-
// This subroutine validates the inputs of distribution system, since node data from a primary airloop
10092-
// are not available in the first call during reading input data of airflownetwork objects.
10093-
// Note: this routine shouldn't be called more than once
10118+
// This subroutine finalizes the inputs of distribution system, since node data from a primary airloop
10119+
// are not available in the first call during reading input data of AirflowNetwork objects.
10120+
// Note: this routine shouldn't be called more than once, which is enforced with the distribution_is_final
10121+
// flag. Some of the validation may be moved to the validate_network function.
10122+
10123+
if (distribution_is_final) {
10124+
return;
10125+
}
1009410126

1009510127
// Using/Aliasing
1009610128
using BranchNodeConnections::GetNodeConnectionType;
@@ -10148,7 +10180,7 @@ namespace AirflowNetwork {
1014810180
"The entered name is " + DisSysNodeData(i).node_name + " in an AirflowNetwork:Distribution:Node object.");
1014910181
ErrorsFound = true;
1015010182
}
10151-
DisSysNodeData(i).EPlusNodeNum = j;
10183+
DisSysNodeData(i).node_number = j;
1015210184
AirflowNetworkNodeData(NumOfNodesMultiZone + i).EPlusNodeNum = j;
1015310185
AirflowNetworkNodeData(NumOfNodesMultiZone + i).AirLoopNum = DisSysNodeData(i).AirLoopNum;
1015410186
NodeFound(j) = true;
@@ -10168,7 +10200,7 @@ namespace AirflowNetwork {
1016810200
ErrorsFound = true;
1016910201
}
1017010202
}
10171-
if (DisSysNodeData(i).EPlusNodeNum == 0) {
10203+
if (DisSysNodeData(i).node_number == 0) {
1017210204
ShowSevereError(m_state,
1017310205
format(RoutineName) +
1017410206
"Primary Air Loop Node is not found in AIRFLOWNETWORK:DISTRIBUTION:NODE = " + DisSysNodeData(i).Name);
@@ -11007,6 +11039,9 @@ namespace AirflowNetwork {
1100711039
}
1100811040
if (NumOfFans > 1) break;
1100911041
}
11042+
11043+
distribution_is_final = true;
11044+
1101011045
if (NumOfFans > 1) {
1101111046
ShowSevereError(m_state,
1101211047
format(RoutineName) + "An AirLoop branch, " + m_state.dataAirSystemsData->PrimaryAirSystems(1).Branch(BranchNum).Name +

tst/EnergyPlus/unit/AirflowNetworkHVAC.unit.cc

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6081,7 +6081,7 @@ TEST_F(EnergyPlusFixture, AirflowNetwork_CheckNumOfFansInAirLoopTest)
60816081
state->dataAirSystemsData->PrimaryAirSystems(1).Branch(1).Comp(1).Name = "CVF";
60826082
state->dataAirSystemsData->PrimaryAirSystems(1).Branch(1).Comp(2).Name = "VAV";
60836083

6084-
ASSERT_THROW(state->afn->validate_distribution(), std::runtime_error);
6084+
ASSERT_THROW(state->afn->finalize_distribution(), std::runtime_error);
60856085

60866086
std::string const error_string = delimited_string({
60876087
" ** Severe ** AirflowNetwork::Solver::validate_distribution: An AirLoop branch, , has two or more fans: CVF,VAV",
@@ -6156,7 +6156,7 @@ TEST_F(EnergyPlusFixture, AirflowNetwork_CheckMultiZoneNodes_NoZoneNode)
61566156
state->dataZoneEquip->ZoneEquipConfig(1).NumReturnNodes = 0;
61576157
state->dataZoneEquip->ZoneEquipConfig(1).IsControlled = true;
61586158

6159-
ASSERT_THROW(state->afn->validate_distribution(), std::runtime_error);
6159+
ASSERT_THROW(state->afn->finalize_distribution(), std::runtime_error);
61606160

61616161
std::string const error_string = delimited_string({
61626162
" ** Severe ** AirflowNetwork::Solver::validate_distribution: 'ATTIC ZONE AIR NODE' is not defined as an AirflowNetwork:Distribution:Node "
@@ -6251,7 +6251,7 @@ TEST_F(EnergyPlusFixture, AirflowNetwork_CheckMultiZoneNodes_NoInletNode)
62516251
state->afn->SplitterNodeNumbers(2) = 0;
62526252

62536253
// MixedAir::NumOAMixers.allocate(1);
6254-
state->afn->validate_distribution();
6254+
state->afn->finalize_distribution();
62556255

62566256
EXPECT_TRUE(compare_err_stream("", true));
62576257
}
@@ -10503,7 +10503,7 @@ TEST_F(EnergyPlusFixture, DISABLED_AirLoopNumTest)
1050310503
state->dataZoneEquip->ZoneEquipConfig(1).ReturnNodeAirLoopNum(1) = 1;
1050410504
state->dataZoneEquip->ZoneEquipConfig(2).InletNodeAirLoopNum(1) = 1;
1050510505
state->dataZoneEquip->ZoneEquipConfig(2).ReturnNodeAirLoopNum(1) = 1;
10506-
state->afn->DisSysNodeData(9).EPlusNodeNum = 50;
10506+
state->afn->DisSysNodeData(9).node_number = 50;
1050710507
// AirflowNetwork::AirflowNetworkExchangeData.allocate(5);
1050810508
state->afn->manage_balance(true);
1050910509
EXPECT_EQ(state->afn->DisSysCompCVFData(1).AirLoopNum, 1);
@@ -10797,7 +10797,7 @@ TEST_F(EnergyPlusFixture, AirflowNetwork_TestNoZoneEqpSupportZoneERV)
1079710797
state->dataHVACStandAloneERV->StandAloneERV(1).HeatExchangerName = "ERV Heat Exchanger";
1079810798

1079910799
// Check validation and expected errors
10800-
ASSERT_THROW(state->afn->validate_distribution(), std::runtime_error);
10800+
ASSERT_THROW(state->afn->finalize_distribution(), std::runtime_error);
1080110801
std::string const error_string = delimited_string({
1080210802
" ** Severe ** AirflowNetwork::Solver::validate_distribution: 'SupplyFanInletNode' is not defined as an AirflowNetwork:Distribution:Node "
1080310803
"object.",
@@ -10978,7 +10978,7 @@ TEST_F(EnergyPlusFixture, AirflowNetwork_TestZoneEqpSupportZoneERV)
1097810978
state->dataHVACStandAloneERV->StandAloneERV(1).HeatExchangerName = "ERV Heat Exchanger";
1097910979

1098010980
// Check validation and expected warning
10981-
state->afn->validate_distribution();
10981+
state->afn->finalize_distribution();
1098210982

1098310983
EXPECT_TRUE(compare_err_stream(
1098410984
" ** Warning ** AirflowNetwork::Solver::validate_distribution: A ZoneHVAC:EnergyRecoveryVentilator is simulated along with an "
@@ -11146,7 +11146,7 @@ TEST_F(EnergyPlusFixture, AirflowNetwork_TestZoneEqpSupportUnbalancedZoneERV)
1114611146
state->dataHVACStandAloneERV->StandAloneERV(1).HeatExchangerName = "ERV Heat Exchanger";
1114711147

1114811148
// Check validation and expected errors
11149-
ASSERT_THROW(state->afn->validate_distribution(), std::runtime_error);
11149+
ASSERT_THROW(state->afn->finalize_distribution(), std::runtime_error);
1115011150
std::string const error_string = delimited_string({
1115111151
" ** Severe ** AirflowNetwork::Solver::validate_distribution: 'SupplyFanInletNode' is not defined as an AirflowNetwork:Distribution:Node "
1115211152
"object.",
@@ -11289,7 +11289,7 @@ TEST_F(EnergyPlusFixture, AirflowNetwork_TestNoZoneEqpSupportHPWH)
1128911289
state->dataWaterThermalTanks->HPWaterHeater(1).FanOutletNode = 3;
1129011290

1129111291
// Check validation and expected errors
11292-
ASSERT_THROW(state->afn->validate_distribution(), std::runtime_error);
11292+
ASSERT_THROW(state->afn->finalize_distribution(), std::runtime_error);
1129311293
std::string const error_string = delimited_string({
1129411294
" ** Severe ** AirflowNetwork::Solver::validate_distribution: 'SupplyFanInletNode' is not defined as an AirflowNetwork:Distribution:Node "
1129511295
"object.",
@@ -11427,7 +11427,7 @@ TEST_F(EnergyPlusFixture, AirflowNetwork_TestZoneEqpSupportHPWH)
1142711427
state->dataWaterThermalTanks->HPWaterHeater(1).FanOutletNode = 3;
1142811428

1142911429
// Check validation and expected warning
11430-
state->afn->validate_distribution();
11430+
state->afn->finalize_distribution();
1143111431
EXPECT_TRUE(compare_err_stream(
1143211432
" ** Warning ** AirflowNetwork::Solver::validate_distribution: Heat pump water heater is simulated along with an AirflowNetwork "
1143311433
"but is not included in the AirflowNetwork.\n",
@@ -11555,7 +11555,7 @@ TEST_F(EnergyPlusFixture, AirflowNetwork_TestZoneEqpSupportHPWHZoneAndOA)
1155511555
state->dataWaterThermalTanks->HPWaterHeater(1).FanOutletNode = 3;
1155611556

1155711557
// Check validation and expected errors
11558-
ASSERT_THROW(state->afn->validate_distribution(), std::runtime_error);
11558+
ASSERT_THROW(state->afn->finalize_distribution(), std::runtime_error);
1155911559
std::string const error_string = delimited_string({
1156011560
" ** Severe ** AirflowNetwork::Solver::validate_distribution: 'SupplyFanInletNode' is not defined as an AirflowNetwork:Distribution:Node "
1156111561
"object.",

0 commit comments

Comments
 (0)