diff --git a/src/EnergyPlus/ReportCoilSelection.cc b/src/EnergyPlus/ReportCoilSelection.cc index e46290b92e2..b4733432d1f 100644 --- a/src/EnergyPlus/ReportCoilSelection.cc +++ b/src/EnergyPlus/ReportCoilSelection.cc @@ -625,45 +625,7 @@ void ReportCoilSelection::doZoneEqSetup(EnergyPlusData &state, int const coilVec } if (c->zoneEqNum > 0) { - c->coilLocation = "Unknown"; - c->typeHVACname = "Unknown"; - c->userNameforHVACsystem = "Unknown"; - // now search equiment - if (state.dataZoneEquip->ZoneEquipList(c->zoneEqNum).NumOfEquipTypes == 1) { // this must be it, fill strings for type and name - c->typeHVACname = state.dataZoneEquip->ZoneEquipList(c->zoneEqNum).EquipTypeName(1); - c->userNameforHVACsystem = state.dataZoneEquip->ZoneEquipList(c->zoneEqNum).EquipName(1); - c->coilLocation = "Zone Equipment"; - c->zoneHVACTypeNum = state.dataZoneEquip->ZoneEquipList(c->zoneEqNum).EquipType(1); - c->zoneHVACIndex = state.dataZoneEquip->ZoneEquipList(c->zoneEqNum).EquipIndex(1); - } else if (state.dataZoneEquip->ZoneEquipList(c->zoneEqNum).NumOfEquipTypes > 1) { - bool foundOne(false); - for (int equipLoop = 1; equipLoop <= state.dataZoneEquip->ZoneEquipList(c->zoneEqNum).NumOfEquipTypes; ++equipLoop) { - // go with the first ZoneHVAC device in the list - DataZoneEquipment::ZoneEquipType equipType = state.dataZoneEquip->ZoneEquipList(c->zoneEqNum).EquipType(equipLoop); - if (equipType == DataZoneEquipment::ZoneEquipType::VariableRefrigerantFlowTerminal || - equipType == DataZoneEquipment::ZoneEquipType::EnergyRecoveryVentilator || - equipType == DataZoneEquipment::ZoneEquipType::FourPipeFanCoil || equipType == DataZoneEquipment::ZoneEquipType::OutdoorAirUnit || - equipType == DataZoneEquipment::ZoneEquipType::PackagedTerminalAirConditioner || - equipType == DataZoneEquipment::ZoneEquipType::PackagedTerminalHeatPump || - equipType == DataZoneEquipment::ZoneEquipType::UnitHeater || equipType == DataZoneEquipment::ZoneEquipType::UnitVentilator || - equipType == DataZoneEquipment::ZoneEquipType::VentilatedSlab || - equipType == DataZoneEquipment::ZoneEquipType::PackagedTerminalHeatPumpWaterToAir || - equipType == DataZoneEquipment::ZoneEquipType::WindowAirConditioner || - equipType == DataZoneEquipment::ZoneEquipType::DehumidifierDX) { - if (!foundOne) { - c->typeHVACname = state.dataZoneEquip->ZoneEquipList(c->zoneEqNum).EquipTypeName(equipLoop); - c->userNameforHVACsystem = state.dataZoneEquip->ZoneEquipList(c->zoneEqNum).EquipName(equipLoop); - foundOne = true; - c->coilLocation = "Zone Equipment"; - c->zoneHVACTypeNum = state.dataZoneEquip->ZoneEquipList(c->zoneEqNum).EquipType(equipLoop); - c->zoneHVACIndex = state.dataZoneEquip->ZoneEquipList(c->zoneEqNum).EquipIndex(equipLoop); - } else { // or may have found another - c->typeHVACname += " or " + state.dataZoneEquip->ZoneEquipList(c->zoneEqNum).EquipTypeName(equipLoop); - c->userNameforHVACsystem += " or " + state.dataZoneEquip->ZoneEquipList(c->zoneEqNum).EquipName(equipLoop); - } - } - } - } + associateZoneCoilWithParent(state, c); } } @@ -675,44 +637,8 @@ void ReportCoilSelection::doFinalProcessingOfCoilData(EnergyPlusData &state) // mine final/hard values from coil models if (c->zoneEqNum > 0) { - c->coilLocation = "Unknown"; - c->typeHVACname = "Unknown"; - c->userNameforHVACsystem = "Unknown"; - // now search equipment - auto const &zoneEquipList = state.dataZoneEquip->ZoneEquipList(c->zoneEqNum); - if (zoneEquipList.NumOfEquipTypes == 1) { // this must be it, fill strings for type and name - c->typeHVACname = zoneEquipList.EquipTypeName(1); - c->userNameforHVACsystem = zoneEquipList.EquipName(1); - c->coilLocation = "Zone Equipment"; - } else if (zoneEquipList.NumOfEquipTypes > 1) { - bool foundOne(false); - for (int equipLoop = 1; equipLoop <= zoneEquipList.NumOfEquipTypes; ++equipLoop) { - // go with the first ZoneHVAC device in the list - DataZoneEquipment::ZoneEquipType equipType = zoneEquipList.EquipType(equipLoop); - if (equipType == DataZoneEquipment::ZoneEquipType::VariableRefrigerantFlowTerminal || - equipType == DataZoneEquipment::ZoneEquipType::EnergyRecoveryVentilator || - equipType == DataZoneEquipment::ZoneEquipType::FourPipeFanCoil || - equipType == DataZoneEquipment::ZoneEquipType::OutdoorAirUnit || - equipType == DataZoneEquipment::ZoneEquipType::PackagedTerminalAirConditioner || - equipType == DataZoneEquipment::ZoneEquipType::PackagedTerminalHeatPump || - equipType == DataZoneEquipment::ZoneEquipType::UnitHeater || equipType == DataZoneEquipment::ZoneEquipType::UnitVentilator || - equipType == DataZoneEquipment::ZoneEquipType::VentilatedSlab || - equipType == DataZoneEquipment::ZoneEquipType::PackagedTerminalHeatPumpWaterToAir || - equipType == DataZoneEquipment::ZoneEquipType::WindowAirConditioner || - equipType == DataZoneEquipment::ZoneEquipType::DehumidifierDX) { - if (!foundOne) { - c->typeHVACname = zoneEquipList.EquipTypeName(equipLoop); - c->userNameforHVACsystem = zoneEquipList.EquipName(equipLoop); - foundOne = true; - c->coilLocation = "Zone Equipment"; - } else { // or may have found another - c->typeHVACname += " or " + zoneEquipList.EquipTypeName(equipLoop); - c->userNameforHVACsystem += " or " + zoneEquipList.EquipName(equipLoop); - } - } - } // for (equipLoop) - } // if (zoneEquipList.numOfEquipTypes > 0) - } // if (c->ZoneEqNum > 0) + associateZoneCoilWithParent(state, c); + } if (c->airloopNum > state.dataHVACGlobal->NumPrimaryAirSys && c->oASysNum > 0) { c->coilLocation = "DOAS AirLoop"; @@ -979,6 +905,94 @@ int ReportCoilSelection::getIndexForOrCreateDataObjFromCoilName(EnergyPlusData & return index; } +void ReportCoilSelection::associateZoneCoilWithParent(EnergyPlusData &state, std::unique_ptr &c) +{ + c->coilLocation = "Unknown"; + c->typeHVACname = "Unknown"; + c->userNameforHVACsystem = "Unknown"; + // now search equipment + auto const &zoneEquipList = state.dataZoneEquip->ZoneEquipList(c->zoneEqNum); + bool coilFound = false; + std::string fanType; + std::string fanName; + auto thisSubCoilLambda = [&c](const DataZoneEquipment::SubEquipmentData &myCoil) { return myCoil.Name == c->coilName_; }; + auto thisSubFanLambda = [](const DataZoneEquipment::SubEquipmentData &myFan) { return myFan.TypeOf.rfind("FAN:", 0) == 0; }; + auto thisSubSubCoilLambda = [&c](const DataZoneEquipment::SubSubEquipmentData &myCoil) { return myCoil.Name == c->coilName_; }; + auto thisSubSubFanLambda = [](const DataZoneEquipment::SubSubEquipmentData &myFan) { return myFan.TypeOf.rfind("FAN:", 0) == 0; }; + + for (int equipLoop = 1; equipLoop <= zoneEquipList.NumOfEquipTypes; ++equipLoop) { + // coil should be found only once, fan could be found multiple times, reset here + // for each type of equipment (equipLoop) only one coil and fan could be found as a pair + bool fanFound = false; + auto &thisSubEq = zoneEquipList.EquipData(equipLoop).SubEquipData; + + // search for coil and fan SubEquipData and return parent type/name and fan type/name for coil reports. + auto const &coilIterator = std::find_if(thisSubEq.begin(), thisSubEq.end(), thisSubCoilLambda); + if (std::find_if(thisSubEq.begin(), thisSubEq.end(), thisSubCoilLambda) != thisSubEq.end()) { + c->typeHVACname = zoneEquipList.EquipTypeName(equipLoop); + c->userNameforHVACsystem = zoneEquipList.EquipName(equipLoop); + c->coilLocation = "Zone Equipment"; + int zoneEqListIndex = Util::FindItemInList(zoneEquipList.Name, state.dataZoneEquip->ZoneEquipList); + if (c->zoneNum.empty()) c->zoneNum.resize(1); + c->zoneNum[0] = zoneEqListIndex; + if (c->zoneName.empty()) c->zoneName.resize(1); + c->zoneName[0] = state.dataHeatBal->Zone(zoneEqListIndex).Name; + coilFound = true; + } + auto const &fanIterator = std::find_if(thisSubEq.begin(), thisSubEq.end(), thisSubFanLambda); + if (fanIterator != thisSubEq.end()) { + unsigned int fanIndex = fanIterator - thisSubEq.begin(); + // notice the brackets on the Array1D for [fanIndex] + fanType = thisSubEq[fanIndex].TypeOf; + fanName = thisSubEq[fanIndex].Name; + fanFound = true; + } + // if coil not found in SubEquipData then maybe it's HXAssisted and in SubSubEquipData. Fan is usually already found if exists. + if (!coilFound || !fanFound) { + for (int subEq = 1; subEq <= zoneEquipList.EquipData(equipLoop).NumSubEquip; ++subEq) { + auto &thisSubSubEq = zoneEquipList.EquipData(equipLoop).SubEquipData(subEq).SubSubEquipData; + if (!coilFound) { + auto const &coilIterator2 = std::find_if(thisSubSubEq.begin(), thisSubSubEq.end(), thisSubSubCoilLambda); + if (coilIterator2 != thisSubSubEq.end()) { + c->typeHVACname = zoneEquipList.EquipTypeName(equipLoop); + c->userNameforHVACsystem = zoneEquipList.EquipName(equipLoop); + c->coilLocation = "Zone Equipment"; + int zoneEqListIndex = Util::FindItemInList(zoneEquipList.Name, state.dataZoneEquip->ZoneEquipList); + if (c->zoneNum.empty()) c->zoneNum.resize(1); + c->zoneNum[0] = zoneEqListIndex; + if (c->zoneName.empty()) c->zoneName.resize(1); + c->zoneName[0] = state.dataHeatBal->Zone(zoneEqListIndex).Name; + coilFound = true; + } + } + if (!fanFound) { + auto const &fanIterator2 = std::find_if(thisSubSubEq.begin(), thisSubSubEq.end(), thisSubSubFanLambda); + if (fanIterator2 != thisSubSubEq.end()) { + unsigned int fanIndex = fanIterator2 - thisSubSubEq.begin(); + // notice the brackets on the Array1D for [fanIndex] + fanType = thisSubSubEq[fanIndex].TypeOf; + fanName = thisSubSubEq[fanIndex].Name; + fanFound = true; + } + } + if (coilFound && fanFound) break; + } + } + if (coilFound) { + if (fanFound) { + c->fanTypeName = fanType; + c->fanAssociatedWithCoilName = fanName; + } + break; + } + + } // for (equipLoop) + + if (c->typeHVACname == "Unknown") { + ShowWarningError(state, format("Parent object not found for zone coil = {}", c->coilName_)); + } +} + void ReportCoilSelection::setRatedCoilConditions(EnergyPlusData &state, std::string const &coilName, // ! user-defined name of the coil std::string const &coilObjName, // coil object name, e.g., Coil:Cooling:Water @@ -1975,6 +1989,20 @@ void ReportCoilSelection::setCoilSupplyFanInfo(EnergyPlusData &state, if (c->supFanNum == 0) c->supFanNum = Fans::GetFanIndex(state, fanName); } +void ReportCoilSelection::setCoilEqNum(EnergyPlusData &state, + std::string const &coilName, + std::string const &coilType, + int const curSysNum, + int const curOASysNum, + int const curZoneEqNum) +{ + int index = getIndexForOrCreateDataObjFromCoilName(state, coilName, coilType); + auto &c(coilSelectionDataObjs[index]); + c->airloopNum = curSysNum; + c->oASysNum = curOASysNum; + c->zoneEqNum = curZoneEqNum; +} + std::string ReportCoilSelection::getTimeText(EnergyPlusData &state, int const timeStepAtPeak) { std::string returnString = ""; diff --git a/src/EnergyPlus/ReportCoilSelection.hh b/src/EnergyPlus/ReportCoilSelection.hh index b06b8b218a0..37567137783 100644 --- a/src/EnergyPlus/ReportCoilSelection.hh +++ b/src/EnergyPlus/ReportCoilSelection.hh @@ -404,6 +404,13 @@ public: // methods HVAC::FanType fanType, int fanIndex); + void setCoilEqNum(EnergyPlusData &state, + std::string const &coilName, + std::string const &coilType, + int const curSysNum, + int const curOASysNum, + int const curZoneEqNum); + static std::string getTimeText(EnergyPlusData &state, int const timeStepAtPeak); bool isCompTypeFan(std::string const &compType // string component type, input object class name @@ -432,6 +439,8 @@ private: // methods std::string const &coilType // idf input object class name of coil ); + void associateZoneCoilWithParent(EnergyPlusData &state, std::unique_ptr &c); + public: // data int numCoilsReported_; std::vector> coilSelectionDataObjs; diff --git a/src/EnergyPlus/VentilatedSlab.cc b/src/EnergyPlus/VentilatedSlab.cc index 6fccd5a9419..b190ddafc75 100644 --- a/src/EnergyPlus/VentilatedSlab.cc +++ b/src/EnergyPlus/VentilatedSlab.cc @@ -763,9 +763,18 @@ namespace VentilatedSlab { DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab, ventSlab.Name + "-OA MIXER", DataLoopNode::NodeFluidType::Air, - DataLoopNode::ConnectionType::Internal, + DataLoopNode::ConnectionType::Outlet, NodeInputManager::CompFluidStream::Primary, ObjectIsNotParent); + ventSlab.ReturnAirNode = GetOnlySingleNode(state, + state.dataIPShortCut->cAlphaArgs(18), + ErrorsFound, + DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab, + ventSlab.Name, + DataLoopNode::NodeFluidType::Air, + DataLoopNode::ConnectionType::Inlet, + NodeInputManager::CompFluidStream::Primary, + ObjectIsParent); ventSlab.RadInNode = GetOnlySingleNode(state, state.dataIPShortCut->cAlphaArgs(19), ErrorsFound, @@ -803,9 +812,18 @@ namespace VentilatedSlab { DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab, ventSlab.Name + "-OA MIXER", DataLoopNode::NodeFluidType::Air, - DataLoopNode::ConnectionType::Internal, + DataLoopNode::ConnectionType::Outlet, NodeInputManager::CompFluidStream::Primary, ObjectIsNotParent); + ventSlab.ReturnAirNode = GetOnlySingleNode(state, + state.dataIPShortCut->cAlphaArgs(18), + ErrorsFound, + DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab, + ventSlab.Name, + DataLoopNode::NodeFluidType::Air, + DataLoopNode::ConnectionType::Inlet, + NodeInputManager::CompFluidStream::Primary, + ObjectIsParent); ventSlab.RadInNode = GetOnlySingleNode(state, state.dataIPShortCut->cAlphaArgs(19), ErrorsFound, @@ -846,6 +864,15 @@ namespace VentilatedSlab { DataLoopNode::ConnectionType::Inlet, NodeInputManager::CompFluidStream::Primary, ObjectIsParent); + ventSlab.ReturnAirNode = GetOnlySingleNode(state, + state.dataIPShortCut->cAlphaArgs(18), + ErrorsFound, + DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab, + ventSlab.Name, + DataLoopNode::NodeFluidType::Air, + DataLoopNode::ConnectionType::Inlet, + NodeInputManager::CompFluidStream::Primary, + ObjectIsParent); ventSlab.ReturnAirNode = GetOnlySingleNode(state, state.dataIPShortCut->cAlphaArgs(18), ErrorsFound, @@ -978,7 +1005,7 @@ namespace VentilatedSlab { // Add fan to component sets array SetUpCompSets(state, CurrentModuleObject, - ventSlab.Name + "-SYSTEM", + ventSlab.Name, "UNDEFINED", state.dataIPShortCut->cAlphaArgs(25), state.dataIPShortCut->cAlphaArgs(23), @@ -1246,7 +1273,7 @@ namespace VentilatedSlab { // Add cooling coil to component sets array when present SetUpCompSets(state, CurrentModuleObject, - ventSlab.Name + "-SYSTEM", + ventSlab.Name, state.dataIPShortCut->cAlphaArgs(30), state.dataIPShortCut->cAlphaArgs(31), state.dataIPShortCut->cAlphaArgs(24), @@ -1255,7 +1282,7 @@ namespace VentilatedSlab { // Add heating coil to component sets array when cooling coil present SetUpCompSets(state, CurrentModuleObject, - ventSlab.Name + "-SYSTEM", + ventSlab.Name, state.dataIPShortCut->cAlphaArgs(27), state.dataIPShortCut->cAlphaArgs(28), "UNDEFINED", @@ -1266,7 +1293,7 @@ namespace VentilatedSlab { // Add heating coil to component sets array when no cooling coil present SetUpCompSets(state, CurrentModuleObject, - ventSlab.Name + "-SYSTEM", + ventSlab.Name, state.dataIPShortCut->cAlphaArgs(27), state.dataIPShortCut->cAlphaArgs(28), state.dataIPShortCut->cAlphaArgs(24), @@ -1277,7 +1304,7 @@ namespace VentilatedSlab { // Add cooling coil to component sets array when no heating coil present SetUpCompSets(state, CurrentModuleObject, - ventSlab.Name + "-SYSTEM", + ventSlab.Name, state.dataIPShortCut->cAlphaArgs(30), state.dataIPShortCut->cAlphaArgs(31), state.dataIPShortCut->cAlphaArgs(24), diff --git a/src/EnergyPlus/WaterCoils.cc b/src/EnergyPlus/WaterCoils.cc index b488f4fb3ca..959fb06816f 100644 --- a/src/EnergyPlus/WaterCoils.cc +++ b/src/EnergyPlus/WaterCoils.cc @@ -1763,6 +1763,8 @@ void InitWaterCoil(EnergyPlusData &state, int const CoilNum, bool const FirstHVA CalcSimpleHeatingCoil(state, CoilNum, HVAC::FanOp::Continuous, 1.0, state.dataWaterCoils->SimCalc); coilTypeName = "Coil:Heating:Water"; } + state.dataRptCoilSelection->coilSelectionReportObj->setCoilEqNum( + state, waterCoil.Name, coilTypeName, state.dataSize->CurSysNum, state.dataSize->CurOASysNum, state.dataSize->CurZoneEqNum); // coil outlets Real64 RatedOutletWetBulb(0.0); diff --git a/tst/EnergyPlus/unit/ReportCoilSelection.unit.cc b/tst/EnergyPlus/unit/ReportCoilSelection.unit.cc index e807026b49e..8f49067b8c5 100644 --- a/tst/EnergyPlus/unit/ReportCoilSelection.unit.cc +++ b/tst/EnergyPlus/unit/ReportCoilSelection.unit.cc @@ -57,6 +57,7 @@ #include #include #include +//#include #include #include #include @@ -319,6 +320,7 @@ TEST_F(EnergyPlusFixture, ReportCoilSelection_ZoneEqCoil) state->dataZoneEquip->ZoneEquipList(curZoneEqNum).EquipName(2) = "Zone 2 Unit Heater"; state->dataZoneEquip->ZoneEquipList(curZoneEqNum).EquipTypeName(2) = "ZoneHVAC:UnitHeater"; state->dataZoneEquip->ZoneEquipList(curZoneEqNum).EquipType(2) = DataZoneEquipment::ZoneEquipType::UnitHeater; + state->dataZoneEquip->ZoneEquipList(curZoneEqNum).EquipData.allocate(3); Real64 totGrossCap = 500.0; Real64 sensGrossCap = 500.0; @@ -579,6 +581,7 @@ TEST_F(EnergyPlusFixture, ReportCoilSelection_ZoneEqCoolingCoil) state->dataZoneEquip->ZoneEquipList(curZoneEqNum).EquipName(2) = "Zone 2 Unit Heater"; state->dataZoneEquip->ZoneEquipList(curZoneEqNum).EquipTypeName(2) = "ZoneHVAC:UnitHeater"; state->dataZoneEquip->ZoneEquipList(curZoneEqNum).EquipType(2) = DataZoneEquipment::ZoneEquipType::UnitHeater; + state->dataZoneEquip->ZoneEquipList(curZoneEqNum).EquipData.allocate(3); Real64 totGrossCap = 500.0; Real64 sensGrossCap = 400.0; @@ -943,3 +946,175 @@ TEST_F(EnergyPlusFixture, ReportCoilSelection_4PipeFCU_ElecHeatingCoil) EXPECT_NEAR(RatedCoilTotCap, c1->coilSensCapAtPeak, 0.1); EXPECT_NEAR(result_sensCapacity, c1->coilSensCapAtPeak, 0.1); } + +TEST_F(EnergyPlusFixture, Test_finishCoilSummaryReportTable) +{ + Real64 constexpr mult = 1.0; + int curSysNum = 0; + int curOASysNum = 0; + int curZoneEqNum = 1; + std::string coil1Name = "ElecHeatCoil"; // user-defined name of the coil + std::string coil1Type = "Coil:Heating:Electric"; // idf input object class name of coil + + // set up coil selection report object by calling a public function (i.e., calls getIndexForOrCreateDataObjFromCoilName) + state->dataRptCoilSelection->coilSelectionReportObj->setCoilReheatMultiplier(*state, coil1Name, coil1Type, mult); + bool isValidCoilType = state->dataRptCoilSelection->coilSelectionReportObj->isCompTypeCoil(coil1Type); + EXPECT_TRUE(isValidCoilType); + auto &c1 = state->dataRptCoilSelection->coilSelectionReportObj->coilSelectionDataObjs[0]; + c1->zoneEqNum = curZoneEqNum; + + state->dataHeatBal->Zone.allocate(1); + state->dataHeatBal->Zone(1).Name = "ThisZone"; + state->dataZoneEquip->ZoneEquipList.allocate(1); + auto &zoneEquipList = state->dataZoneEquip->ZoneEquipList(curZoneEqNum); + + zoneEquipList.NumOfEquipTypes = 1; + zoneEquipList.EquipName.allocate(1); + zoneEquipList.EquipTypeName.allocate(1); + zoneEquipList.EquipData.allocate(1); + zoneEquipList.EquipType.allocate(1); + zoneEquipList.EquipName(1) = "Zone 1 FCU"; + zoneEquipList.EquipTypeName(1) = "ZoneHVAC:FourPipeFanCoil"; + zoneEquipList.EquipType(1) = DataZoneEquipment::ZoneEquipType::FourPipeFanCoil; + zoneEquipList.EquipData(1).Name = "ZoneHVAC:FourPipeFanCoil"; + zoneEquipList.EquipData(1).NumSubEquip = 2; + zoneEquipList.EquipData(1).SubEquipData.allocate(2); + zoneEquipList.EquipData(1).SubEquipData(1).Name = "ElecHeatCoil"; + zoneEquipList.EquipData(1).SubEquipData(1).TypeOf = "Coil:Heating:Electric"; + zoneEquipList.EquipData(1).SubEquipData(2).Name = "MyFan1"; + zoneEquipList.EquipData(1).SubEquipData(2).TypeOf = "FAN:ONOFF"; + + // test that 1 equipment in the equipment list has data that is read from EquipmentList data. + EXPECT_TRUE(Util::SameString(c1->coilLocation, "unknown")); + EXPECT_TRUE(Util::SameString(c1->typeHVACname, "unknown")); + EXPECT_TRUE(Util::SameString(c1->userNameforHVACsystem, "unknown")); + + state->dataRptCoilSelection->coilSelectionReportObj->finishCoilSummaryReportTable(*state); + + EXPECT_TRUE(Util::SameString(c1->coilLocation, "Zone Equipment")); + EXPECT_TRUE(Util::SameString(c1->typeHVACname, "ZoneHVAC:FourPipeFanCoil")); + EXPECT_TRUE(Util::SameString(c1->userNameforHVACsystem, "Zone 1 FCU")); + EXPECT_TRUE(Util::SameString(c1->zoneName[0], "ThisZone")); + EXPECT_TRUE(Util::SameString(c1->fanTypeName, "FAN:ONOFF")); + EXPECT_TRUE(Util::SameString(c1->fanAssociatedWithCoilName, "MyFan1")); + + // add another coil and hvac system and increase equipment list to 2 + zoneEquipList.NumOfEquipTypes = 2; + zoneEquipList.EquipName.allocate(2); + zoneEquipList.EquipTypeName.allocate(2); + zoneEquipList.EquipData.allocate(2); + zoneEquipList.EquipType.allocate(2); + zoneEquipList.EquipIndex.allocate(2); + + EXPECT_TRUE(Util::SameString(zoneEquipList.EquipName(1), "")); // equipment list data is cleared + EXPECT_TRUE(Util::SameString(zoneEquipList.EquipName(2), "")); + + // test that 2 equipment in the equipment list will fill coil selection data + std::string coil2Name = "ElecHeatCoil 2"; // user-defined name of the coil + std::string coil2Type = "Coil:Heating:Electric"; // idf input object class name of coil + + zoneEquipList.EquipName(1) = "Zone 1 FCU"; + zoneEquipList.EquipTypeName(1) = "ZoneHVAC:FourPipeFanCoil"; + zoneEquipList.EquipType(1) = DataZoneEquipment::ZoneEquipType::FourPipeFanCoil; + zoneEquipList.EquipData(1).Name = "ZoneHVAC:FourPipeFanCoil"; + zoneEquipList.EquipData(1).NumSubEquip = 2; + zoneEquipList.EquipData(1).SubEquipData.allocate(2); + zoneEquipList.EquipData(1).SubEquipData(1).Name = coil1Name; + zoneEquipList.EquipData(1).SubEquipData(2).Name = "MyFan1"; + zoneEquipList.EquipData(1).SubEquipData(2).TypeOf = "FAN:ONOFF"; + + zoneEquipList.EquipName(2) = "Zone 1 ADU"; + zoneEquipList.EquipTypeName(2) = "ZoneHVAC:AirDistributionUnit"; + zoneEquipList.EquipType(2) = DataZoneEquipment::ZoneEquipType::AirDistributionUnit; + zoneEquipList.EquipData(2).Name = "Zone 1 ADU"; + zoneEquipList.EquipData(2).NumSubEquip = 1; + zoneEquipList.EquipData(2).SubEquipData.allocate(1); + zoneEquipList.EquipData(2).SubEquipData(1).Name = "AIRTERMINAL:SINGLEDUCT:VAV:REHEAT"; + zoneEquipList.EquipData(2).SubEquipData(1).NumSubSubEquip = 1; + zoneEquipList.EquipData(2).SubEquipData(1).SubSubEquipData.allocate(1); + zoneEquipList.EquipData(2).SubEquipData(1).SubSubEquipData(1).Name = coil2Name; + + // set up coil selection report object by calling a public function that calls getIndexForOrCreateDataObjFromCoilName + state->dataRptCoilSelection->coilSelectionReportObj->setCoilReheatMultiplier(*state, coil2Name, coil2Type, mult); + auto &c1a = state->dataRptCoilSelection->coilSelectionReportObj->coilSelectionDataObjs[0]; + auto &c2a = state->dataRptCoilSelection->coilSelectionReportObj->coilSelectionDataObjs[1]; + c2a->zoneEqNum = curZoneEqNum; + + EXPECT_TRUE(Util::SameString(c2a->coilLocation, "unknown")); + EXPECT_TRUE(Util::SameString(c2a->typeHVACname, "unknown")); + EXPECT_TRUE(Util::SameString(c2a->userNameforHVACsystem, "unknown")); + + state->dataRptCoilSelection->coilSelectionReportObj->finishCoilSummaryReportTable(*state); + + EXPECT_TRUE(Util::SameString(c1a->coilLocation, "Zone Equipment")); + EXPECT_TRUE(Util::SameString(c1a->typeHVACname, "ZoneHVAC:FourPipeFanCoil")); + EXPECT_TRUE(Util::SameString(c1a->userNameforHVACsystem, "Zone 1 FCU")); + EXPECT_TRUE(Util::SameString(c1a->coilName_, coil1Name)); + EXPECT_TRUE(Util::SameString(c1a->zoneName[0], "ThisZone")); + EXPECT_TRUE(Util::SameString(c1a->fanTypeName, "FAN:ONOFF")); + EXPECT_TRUE(Util::SameString(c1a->fanAssociatedWithCoilName, "MyFan1")); + + EXPECT_TRUE(Util::SameString(c2a->coilLocation, "Zone Equipment")); + EXPECT_TRUE(Util::SameString(c2a->typeHVACname, "ZoneHVAC:AirDistributionUnit")); + EXPECT_TRUE(Util::SameString(c2a->userNameforHVACsystem, "Zone 1 ADU")); + EXPECT_TRUE(Util::SameString(c2a->coilName_, coil2Name)); + EXPECT_TRUE(Util::SameString(c2a->zoneName[0], "ThisZone")); + + // check equipment order and note coil1Name is associated with 4PipeFanCoil + EXPECT_ENUM_EQ(zoneEquipList.EquipType(1), DataZoneEquipment::ZoneEquipType::FourPipeFanCoil); + EXPECT_TRUE(Util::SameString(zoneEquipList.EquipData(1).SubEquipData(1).Name, coil1Name)); + EXPECT_ENUM_EQ(zoneEquipList.EquipType(2), DataZoneEquipment::ZoneEquipType::AirDistributionUnit); + EXPECT_TRUE(Util::SameString(zoneEquipList.EquipData(2).SubEquipData(1).SubSubEquipData(1).Name, coil2Name)); + + // delete coil report objects to start from scratch + state->dataRptCoilSelection->coilSelectionReportObj->numCoilsReported_ = 0; + state->dataRptCoilSelection->coilSelectionReportObj.reset(nullptr); + createCoilSelectionReportObj(*state); + + // switch coil order in coil reports to try to find issues + state->dataRptCoilSelection->coilSelectionReportObj->setCoilReheatMultiplier(*state, coil2Name, coil2Type, mult); + state->dataRptCoilSelection->coilSelectionReportObj->setCoilReheatMultiplier(*state, coil1Name, coil1Type, mult); + auto &c1b = state->dataRptCoilSelection->coilSelectionReportObj->coilSelectionDataObjs[0]; + auto &c2b = state->dataRptCoilSelection->coilSelectionReportObj->coilSelectionDataObjs[1]; + c1b->zoneEqNum = curZoneEqNum; + c2b->zoneEqNum = curZoneEqNum; + + // switch the equipment order to try to find issues + std::string tmpEquipName = zoneEquipList.EquipName(1); + std::string tmpEquipTypeName = zoneEquipList.EquipTypeName(1); + auto tmpEqData = zoneEquipList.EquipData(1); + auto tmpEquipType = zoneEquipList.EquipType(1); + + zoneEquipList.EquipName(1) = zoneEquipList.EquipName(2); + zoneEquipList.EquipTypeName(1) = zoneEquipList.EquipTypeName(2); + zoneEquipList.EquipType(1) = zoneEquipList.EquipType(2); + zoneEquipList.EquipData(1) = zoneEquipList.EquipData(2); + + zoneEquipList.EquipName(2) = tmpEquipName; + zoneEquipList.EquipTypeName(2) = tmpEquipTypeName; + zoneEquipList.EquipType(2) = tmpEquipType; + zoneEquipList.EquipData(2) = tmpEqData; + + // check that equipment order is reversed in equipment list and note coil1Name is associated with 4PipeFanCoil + EXPECT_ENUM_EQ(zoneEquipList.EquipType(1), DataZoneEquipment::ZoneEquipType::AirDistributionUnit); + EXPECT_TRUE(Util::SameString(zoneEquipList.EquipData(1).SubEquipData(1).SubSubEquipData(1).Name, coil2Name)); + EXPECT_ENUM_EQ(zoneEquipList.EquipType(2), DataZoneEquipment::ZoneEquipType::FourPipeFanCoil); + EXPECT_TRUE(Util::SameString(zoneEquipList.EquipData(2).SubEquipData(1).Name, coil1Name)); + + state->dataRptCoilSelection->coilSelectionReportObj->finishCoilSummaryReportTable(*state); + + EXPECT_TRUE(Util::SameString(c1b->coilLocation, "Zone Equipment")); + EXPECT_TRUE(Util::SameString(c1b->typeHVACname, "ZoneHVAC:AirDistributionUnit")); + EXPECT_TRUE(Util::SameString(c1b->userNameforHVACsystem, "Zone 1 ADU")); + EXPECT_TRUE(Util::SameString(c1b->coilName_, coil2Name)); + EXPECT_TRUE(Util::SameString(c1b->zoneName[0], "ThisZone")); + + // note coil1Name is associated with 4PipeFanCoil + EXPECT_TRUE(Util::SameString(c2b->coilLocation, "Zone Equipment")); + EXPECT_TRUE(Util::SameString(c2b->typeHVACname, "ZoneHVAC:FourPipeFanCoil")); + EXPECT_TRUE(Util::SameString(c2b->userNameforHVACsystem, "Zone 1 FCU")); + EXPECT_TRUE(Util::SameString(c2b->coilName_, coil1Name)); + EXPECT_TRUE(Util::SameString(c2b->zoneName[0], "ThisZone")); + EXPECT_TRUE(Util::SameString(c2b->fanTypeName, "FAN:ONOFF")); + EXPECT_TRUE(Util::SameString(c2b->fanAssociatedWithCoilName, "MyFan1")); +}