From 234436d5e6b805781eacc6213d2c001db8ac1183 Mon Sep 17 00:00:00 2001 From: Julien Marrec Date: Thu, 11 Dec 2025 12:26:01 +0100 Subject: [PATCH 1/7] #5547 - Move HPWH air inlet/outlet node naming to model namespace for EMS --- ...ateWaterHeaterHeatPumpWrappedCondenser.cpp | 66 ++++++++++--------- .../WaterHeaterHeatPumpWrappedCondenser.cpp | 55 ++++++++++++++++ .../WaterHeaterHeatPumpWrappedCondenser.hpp | 8 +++ ...terHeaterHeatPumpWrappedCondenser_Impl.hpp | 3 + 4 files changed, 102 insertions(+), 30 deletions(-) diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateWaterHeaterHeatPumpWrappedCondenser.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateWaterHeaterHeatPumpWrappedCondenser.cpp index af2bf8b9da3..52543de3471 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateWaterHeaterHeatPumpWrappedCondenser.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateWaterHeaterHeatPumpWrappedCondenser.cpp @@ -108,8 +108,10 @@ namespace energyplus { } } - std::string airInletNodeName; - std::string airOutletNodeName; + // Logic is in model namespace for these two for EMS, cf #5547 + std::string airInletNodeName = modelObject.airInletNodeName(); + std::string airOutletNodeName = modelObject.airOutletNodeName(); + std::string outdoorAirNodeName; std::string exhaustAirNodeName; std::string inletAirZoneName; @@ -126,15 +128,19 @@ namespace energyplus { if (istringEqual(modelObject.fanPlacement(), "DrawThrough")) { idfObject.setString(WaterHeater_HeatPump_WrappedCondenserFields::FanPlacement, "DrawThrough"); + // Depending on inletAirConfiguration, what this returns will be different + // * "ZoneAirOnly" and "ZoneAndOutdoorAir" need to get nodes from the thermal zone + // * "OutdoorAirOnly" and "Schedule", it just constructs a node name. + // This is helpful if you need to control this via EMS if (istringEqual(inletAirConfiguration, "ZoneAirOnly")) { if (auto thermalZone = modelObject.thermalZone()) { - auto inletNode = modelObject.inletNode(); - OS_ASSERT(inletNode); - airInletNodeName = inletNode->name().get(); + // auto inletNode = modelObject.inletNode(); + // OS_ASSERT(inletNode); + // airInletNodeName = inletNode->name().get(); - auto outletNode = modelObject.outletNode(); - OS_ASSERT(outletNode); - airOutletNodeName = outletNode->name().get(); + // auto outletNode = modelObject.outletNode(); + // OS_ASSERT(outletNode); + // airOutletNodeName = outletNode->name().get(); inletAirZoneName = thermalZone->name().get(); fanInletNodeName = modelObject.name().get() + " Evap Outlet - Fan Inlet"; @@ -144,13 +150,13 @@ namespace energyplus { } } else if (istringEqual(inletAirConfiguration, "ZoneAndOutdoorAir")) { if (auto thermalZone = modelObject.thermalZone()) { - auto inletNode = modelObject.inletNode(); - OS_ASSERT(inletNode); - airInletNodeName = inletNode->name().get(); + // auto inletNode = modelObject.inletNode(); + // OS_ASSERT(inletNode); + // airInletNodeName = inletNode->name().get(); - auto outletNode = modelObject.outletNode(); - OS_ASSERT(outletNode); - airOutletNodeName = outletNode->name().get(); + // auto outletNode = modelObject.outletNode(); + // OS_ASSERT(outletNode); + // airOutletNodeName = outletNode->name().get(); outdoorAirNodeName = modelObject.name().get() + " Outdoor Air"; exhaustAirNodeName = modelObject.name().get() + " Exhaust Air"; @@ -170,8 +176,8 @@ namespace energyplus { evapInletNodeName = outdoorAirNodeName; evapOutletNodeName = fanInletNodeName; } else if (istringEqual(inletAirConfiguration, "Schedule")) { - airInletNodeName = modelObject.name().get() + " Inlet"; - airOutletNodeName = modelObject.name().get() + " Outlet"; + // airInletNodeName = modelObject.name().get() + " Inlet"; + // airOutletNodeName = modelObject.name().get() + " Outlet"; fanInletNodeName = modelObject.name().get() + " Evap Outlet - Fan Inlet"; fanOutletNodeName = airOutletNodeName; evapInletNodeName = airInletNodeName; @@ -183,13 +189,13 @@ namespace energyplus { if (istringEqual(inletAirConfiguration, "ZoneAirOnly")) { if (auto thermalZone = modelObject.thermalZone()) { - auto inletNode = modelObject.inletNode(); - OS_ASSERT(inletNode); - airInletNodeName = inletNode->name().get(); + // auto inletNode = modelObject.inletNode(); + // OS_ASSERT(inletNode); + // airInletNodeName = inletNode->name().get(); - auto outletNode = modelObject.outletNode(); - OS_ASSERT(outletNode); - airOutletNodeName = outletNode->name().get(); + // auto outletNode = modelObject.outletNode(); + // OS_ASSERT(outletNode); + // airOutletNodeName = outletNode->name().get(); inletAirZoneName = thermalZone->name().get(); fanInletNodeName = airInletNodeName; @@ -199,13 +205,13 @@ namespace energyplus { } } else if (istringEqual(inletAirConfiguration, "ZoneAndOutdoorAir")) { if (auto thermalZone = modelObject.thermalZone()) { - auto inletNode = modelObject.inletNode(); - OS_ASSERT(inletNode); - airInletNodeName = inletNode->name().get(); + // auto inletNode = modelObject.inletNode(); + // OS_ASSERT(inletNode); + // airInletNodeName = inletNode->name().get(); - auto outletNode = modelObject.outletNode(); - OS_ASSERT(outletNode); - airOutletNodeName = outletNode->name().get(); + // auto outletNode = modelObject.outletNode(); + // OS_ASSERT(outletNode); + // airOutletNodeName = outletNode->name().get(); outdoorAirNodeName = modelObject.name().get() + " Outdoor Air"; exhaustAirNodeName = modelObject.name().get() + " Exhaust Air"; @@ -225,8 +231,8 @@ namespace energyplus { evapInletNodeName = fanOutletNodeName; evapOutletNodeName = exhaustAirNodeName; } else if (istringEqual(inletAirConfiguration, "Schedule")) { - airInletNodeName = modelObject.name().get() + " Inlet"; - airOutletNodeName = modelObject.name().get() + " Outlet"; + // airInletNodeName = modelObject.name().get() + " Inlet"; + // airOutletNodeName = modelObject.name().get() + " Outlet"; fanInletNodeName = airInletNodeName; fanOutletNodeName = modelObject.name().get() + " Fan Outlet - Evap Inlet"; evapInletNodeName = fanOutletNodeName; diff --git a/src/model/WaterHeaterHeatPumpWrappedCondenser.cpp b/src/model/WaterHeaterHeatPumpWrappedCondenser.cpp index 8da4f2a26a7..f0653bca824 100644 --- a/src/model/WaterHeaterHeatPumpWrappedCondenser.cpp +++ b/src/model/WaterHeaterHeatPumpWrappedCondenser.cpp @@ -14,6 +14,7 @@ #include "HVACComponent_Impl.hpp" #include "FanOnOff.hpp" #include "FanOnOff_Impl.hpp" +#include "Node.hpp" // #include "FanSystemModel.hpp" #include "WaterToWaterComponent.hpp" #include "WaterToWaterComponent_Impl.hpp" @@ -144,6 +145,52 @@ namespace model { return value.get(); } + std::string WaterHeaterHeatPumpWrappedCondenser_Impl::airInletNodeName() const { + auto inletAirConfiguration = this->inletAirConfiguration(); + + std::string airInletNodeName; + // Depending on inletAirConfiguration, what this returns will be different + // * "ZoneAirOnly" and "ZoneAndOutdoorAir" need to get nodes from the thermal zone + // * "OutdoorAirOnly" and "Schedule", it just constructs a node name. + // This is helpful if you need to control this via EMS + if (istringEqual(inletAirConfiguration, "ZoneAirOnly") || istringEqual(inletAirConfiguration, "ZoneAndOutdoorAir")) { + if (auto thermalZone = this->thermalZone()) { + auto inletNode = this->inletNode(); + OS_ASSERT(inletNode); + airInletNodeName = inletNode->nameString(); + } + } else if (istringEqual(inletAirConfiguration, "OutdoorAirOnly")) { + // Empty + } else if (istringEqual(inletAirConfiguration, "Schedule")) { + airInletNodeName = this->nameString() + " Inlet"; + } + + return airInletNodeName; + } + + std::string WaterHeaterHeatPumpWrappedCondenser_Impl::airOutletNodeName() const { + auto inletAirConfiguration = this->inletAirConfiguration(); + + std::string airOutletNodeName; + // Depending on inletAirConfiguration, what this returns will be different + // * "ZoneAirOnly" and "ZoneAndOutdoorAir" need to get nodes from the thermal zone + // * "OutdoorAirOnly" and "Schedule", it just constructs a node name. + // This is helpful if you need to control this via EMS + if (istringEqual(inletAirConfiguration, "ZoneAirOnly") || istringEqual(inletAirConfiguration, "ZoneAndOutdoorAir")) { + if (auto thermalZone = this->thermalZone()) { + auto outletNode = this->outletNode(); + OS_ASSERT(outletNode); + airOutletNodeName = outletNode->nameString(); + } + } else if (istringEqual(inletAirConfiguration, "OutdoorAirOnly")) { + // Empty + } else if (istringEqual(inletAirConfiguration, "Schedule")) { + airOutletNodeName = this->nameString() + " Outlet"; + } + + return airOutletNodeName; + } + boost::optional WaterHeaterHeatPumpWrappedCondenser_Impl::inletAirTemperatureSchedule() const { return getObject().getModelObjectTarget(OS_WaterHeater_HeatPump_WrappedCondenserFields::InletAirTemperatureScheduleName); } @@ -706,6 +753,14 @@ namespace model { return getImpl()->inletAirConfiguration(); } + std::string WaterHeaterHeatPumpWrappedCondenser::airInletNodeName() const { + return getImpl()->airInletNodeName(); + } + + std::string WaterHeaterHeatPumpWrappedCondenser::airOutletNodeName() const { + return getImpl()->airOutletNodeName(); + } + boost::optional WaterHeaterHeatPumpWrappedCondenser::inletAirTemperatureSchedule() const { return getImpl()->inletAirTemperatureSchedule(); } diff --git a/src/model/WaterHeaterHeatPumpWrappedCondenser.hpp b/src/model/WaterHeaterHeatPumpWrappedCondenser.hpp index ff068b56f82..0689c5fbc86 100644 --- a/src/model/WaterHeaterHeatPumpWrappedCondenser.hpp +++ b/src/model/WaterHeaterHeatPumpWrappedCondenser.hpp @@ -184,6 +184,14 @@ namespace model { /** @name Other */ //@{ + /** Convenience methods to return the name of the inlet/outlet nodes + * Depending on inletAirConfiguration, what this returns will be different + * - "ZoneAirOnly" and "ZoneAndOutdoorAir" need to get nodes from the thermal zone + * - "OutdoorAirOnly" and "Schedule", it just constructs a node name. + * This is helpful if you need to control this via EMS */ + std::string airInletNodeName() const; + std::string airOutletNodeName() const; + //@} protected: /// @cond diff --git a/src/model/WaterHeaterHeatPumpWrappedCondenser_Impl.hpp b/src/model/WaterHeaterHeatPumpWrappedCondenser_Impl.hpp index c57e8d468fd..13042939997 100644 --- a/src/model/WaterHeaterHeatPumpWrappedCondenser_Impl.hpp +++ b/src/model/WaterHeaterHeatPumpWrappedCondenser_Impl.hpp @@ -186,6 +186,9 @@ namespace model { bool addToThermalZone(ThermalZone& thermalZone) override; std::vector remove() override; + std::string airInletNodeName() const; + std::string airOutletNodeName() const; + //@} protected: private: From fd7dee0b055272c3f8969e22dcb219a8c31aabb1 Mon Sep 17 00:00:00 2001 From: Alex Chapin Date: Thu, 11 Dec 2025 14:48:37 -0500 Subject: [PATCH 2/7] switched to develop branch for GHA incremental --- .github/workflows/incremental-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/incremental-build.yml b/.github/workflows/incremental-build.yml index 971f78b494a..bff39048c55 100644 --- a/.github/workflows/incremental-build.yml +++ b/.github/workflows/incremental-build.yml @@ -4,7 +4,7 @@ on: pull_request: push: branches: - - main + - develop concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} From edbfbfc660daefef4c72958d38258bc7a87daba5 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Mon, 15 Dec 2025 09:50:58 -0700 Subject: [PATCH 3/7] Add model and ft tests for WaterHeaterHeatPumpWrappedCondenser. --- src/energyplus/CMakeLists.txt | 1 + ...erHeaterHeatPumpWrappedCondenser_GTest.cpp | 244 ++++++++++++++++++ ...erHeaterHeatPumpWrappedCondenser_GTest.cpp | 14 + 3 files changed, 259 insertions(+) create mode 100644 src/energyplus/Test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp diff --git a/src/energyplus/CMakeLists.txt b/src/energyplus/CMakeLists.txt index 5cfa5d7497c..306cb07c83f 100644 --- a/src/energyplus/CMakeLists.txt +++ b/src/energyplus/CMakeLists.txt @@ -856,6 +856,7 @@ set(${target_name}_test_src Test/ThermostatSetpointDualSetpoint_GTest.cpp Test/UnitarySystemPerformanceMultispeed_GTest.cpp Test/WindowPropertyFrameAndDivider_GTest.cpp + Test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp Test/WaterHeaterMixed_GTest.cpp Test/WaterHeaterSizing_GTest.cpp Test/WaterHeaterStratified_GTest.cpp diff --git a/src/energyplus/Test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp b/src/energyplus/Test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp new file mode 100644 index 00000000000..8c0c7305241 --- /dev/null +++ b/src/energyplus/Test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp @@ -0,0 +1,244 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC. +* See also https://openstudio.net/license +***********************************************************************************************************************/ + +#include +#include "EnergyPlusFixture.hpp" + +#include "../ForwardTranslator.hpp" + +#include "../../model/Model.hpp" +#include "../../model/CoilWaterHeatingAirToWaterHeatPumpWrapped.hpp" +#include "../../model/CoilWaterHeatingAirToWaterHeatPumpWrapped_Impl.hpp" +#include "../../model/WaterHeaterHeatPumpWrappedCondenser.hpp" +#include "../../model/ThermalZone.hpp" +#include "../../model/Space.hpp" +#include "../../model/ScheduleConstant.hpp" +#include "../../model/ScheduleConstant_Impl.hpp" +#include "../../model/WaterHeaterStratified.hpp" +#include "../../model/WaterHeaterStratified_Impl.hpp" +#include "../../model/FanOnOff.hpp" +#include "../../model/FanOnOff_Impl.hpp" +#include "../../model/PlantLoop.hpp" +#include "../../model/PlantLoop_Impl.hpp" +#include "../../model/Node.hpp" +#include "../../model/Node_Impl.hpp" + +#include +#include + +using namespace openstudio::energyplus; +using namespace openstudio::model; +using namespace openstudio; + +TEST_F(EnergyPlusFixture, ForwardTranslator_WaterHeaterHeatPumpWrappedCondenser_addToThermalZone) { + Model m; + + WaterHeaterStratified tank(m); + CoilWaterHeatingAirToWaterHeatPumpWrapped coil(m); + FanOnOff fan(m); + + WaterHeaterHeatPumpWrappedCondenser hpwh(m); + + hpwh.setName("My WaterHeaterHeatPumpWrappedCondenser"); + Schedule availabilitySchedule = m.alwaysOnDiscreteSchedule(); + EXPECT_TRUE(hpwh.setAvailabilitySchedule(availabilitySchedule)); + ScheduleConstant scheduleConstant1(m); + scheduleConstant1.setValue(0.1); + EXPECT_TRUE(hpwh.setCompressorSetpointTemperatureSchedule(scheduleConstant1)); + EXPECT_TRUE(hpwh.setDeadBandTemperatureDifference(1)); + EXPECT_TRUE(hpwh.setCondenserBottomLocation(2)); + EXPECT_TRUE(hpwh.setCondenserTopLocation(3)); + EXPECT_TRUE(hpwh.setEvaporatorAirFlowRate(4)); + EXPECT_TRUE(hpwh.setInletAirConfiguration("Schedule")); + ScheduleConstant scheduleConstant2(m); + scheduleConstant2.setValue(0.2); + EXPECT_TRUE(hpwh.setInletAirTemperatureSchedule(scheduleConstant2)); + ScheduleConstant scheduleConstant3(m); + scheduleConstant3.setValue(0.3); + EXPECT_TRUE(hpwh.setInletAirHumiditySchedule(scheduleConstant3)); + EXPECT_TRUE(hpwh.setTank(tank)); + EXPECT_TRUE(hpwh.setDXCoil(coil)); + EXPECT_TRUE(hpwh.setMinimumInletAirTemperatureforCompressorOperation(15)); + EXPECT_TRUE(hpwh.setMaximumInletAirTemperatureforCompressorOperation(30)); + EXPECT_TRUE(hpwh.setCompressorLocation("Outdoors")); + ScheduleConstant scheduleConstant4(m); + scheduleConstant4.setValue(0.4); + EXPECT_TRUE(hpwh.setCompressorAmbientTemperatureSchedule(scheduleConstant4)); + EXPECT_TRUE(hpwh.setFan(fan)); + EXPECT_TRUE(hpwh.setFanPlacement("DrawThrough")); + EXPECT_TRUE(hpwh.setOnCycleParasiticElectricLoad(40)); + EXPECT_TRUE(hpwh.setOffCycleParasiticElectricLoad(50)); + EXPECT_TRUE(hpwh.setParasiticHeatRejectionLocation("Zone")); + ScheduleConstant scheduleConstant5(m); + scheduleConstant5.setValue(0.5); + EXPECT_TRUE(hpwh.setInletAirMixerSchedule(scheduleConstant5)); + EXPECT_TRUE(hpwh.setTankElementControlLogic("Simultaneous")); + EXPECT_TRUE(hpwh.setControlSensor1HeightInStratifiedTank(60)); + EXPECT_TRUE(hpwh.setControlSensor1Weight(0.75)); + EXPECT_TRUE(hpwh.setControlSensor2HeightInStratifiedTank(70)); + + ThermalZone tz(m); + Space space(m); + space.setThermalZone(tz); + + EXPECT_TRUE(hpwh.addToThermalZone(tz)); + + ForwardTranslator ft; + const Workspace w = ft.translateModel(m); + + const auto idfObjs = w.getObjectsByType(IddObjectType::WaterHeater_HeatPump_WrappedCondenser); + ASSERT_EQ(1u, idfObjs.size()); + const auto& idfObject = idfObjs.front(); + + EXPECT_EQ(hpwh.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::Name).get()); + EXPECT_EQ(availabilitySchedule.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::AvailabilityScheduleName).get()); + EXPECT_EQ(scheduleConstant1.nameString(), + idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::CompressorSetpointTemperatureScheduleName).get()); + EXPECT_EQ(1, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::DeadBandTemperatureDifference).get()); + EXPECT_EQ(2, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::CondenserBottomLocation).get()); + EXPECT_EQ(3, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::CondenserTopLocation).get()); + EXPECT_EQ(4, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::EvaporatorAirFlowRate).get()); + EXPECT_EQ("ZoneAirOnly", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::InletAirConfiguration).get()); + ASSERT_TRUE(hpwh.inletNode()); + EXPECT_EQ(hpwh.inletNode()->nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::AirInletNodeName).get()); + ASSERT_TRUE(hpwh.outletNode()); + EXPECT_EQ(hpwh.outletNode()->nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::AirOutletNodeName).get()); + EXPECT_TRUE(idfObject.isEmpty(WaterHeater_HeatPump_WrappedCondenserFields::OutdoorAirNodeName)); + EXPECT_TRUE(idfObject.isEmpty(WaterHeater_HeatPump_WrappedCondenserFields::ExhaustAirNodeName)); + EXPECT_EQ(scheduleConstant2.nameString(), + idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::InletAirTemperatureScheduleName).get()); + EXPECT_EQ(scheduleConstant3.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::InletAirHumidityScheduleName).get()); + EXPECT_EQ(tz.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::InletAirZoneName).get()); + EXPECT_EQ("WaterHeater:Stratified", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::TankObjectType).get()); + EXPECT_EQ(tank.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::TankName).get()); + EXPECT_EQ(tank.supplyInletModelObject()->name().get(), + idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::TankUseSideInletNodeName).get()); + EXPECT_EQ(tank.supplyOutletModelObject()->name().get(), + idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::TankUseSideOutletNodeName).get()); + EXPECT_EQ("Coil:WaterHeating:AirToWaterHeatPump:Wrapped", + idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::DXCoilObjectType).get()); + EXPECT_EQ(coil.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::DXCoilName).get()); + EXPECT_EQ(15, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::MinimumInletAirTemperatureforCompressorOperation).get()); + EXPECT_EQ(30, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::MaximumInletAirTemperatureforCompressorOperation).get()); + EXPECT_EQ("Zone", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::CompressorLocation).get()); + EXPECT_TRUE(idfObject.isEmpty(WaterHeater_HeatPump_WrappedCondenserFields::CompressorAmbientTemperatureScheduleName)); + EXPECT_EQ("Fan:OnOff", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::FanObjectType).get()); + EXPECT_EQ(fan.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::FanName).get()); + EXPECT_EQ("DrawThrough", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::FanPlacement).get()); + EXPECT_EQ(40, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::OnCycleParasiticElectricLoad).get()); + EXPECT_EQ(50, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::OffCycleParasiticElectricLoad).get()); + EXPECT_EQ("Zone", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::ParasiticHeatRejectionLocation).get()); + EXPECT_TRUE(idfObject.isEmpty(WaterHeater_HeatPump_WrappedCondenserFields::InletAirMixerNodeName)); + EXPECT_TRUE(idfObject.isEmpty(WaterHeater_HeatPump_WrappedCondenserFields::OutletAirSplitterNodeName)); + EXPECT_EQ(scheduleConstant5.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::InletAirMixerScheduleName).get()); + EXPECT_EQ("Simultaneous", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::TankElementControlLogic).get()); + EXPECT_EQ(60, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::ControlSensor1HeightInStratifiedTank).get()); + EXPECT_EQ(0.75, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::ControlSensor1Weight).get()); + EXPECT_EQ(70, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::ControlSensor2HeightInStratifiedTank).get()); +} + +TEST_F(EnergyPlusFixture, ForwardTranslator_WaterHeaterHeatPumpWrappedCondenser_addSupplyBranchForComponent) { + Model m; + + WaterHeaterStratified tank(m); + CoilWaterHeatingAirToWaterHeatPumpWrapped coil(m); + FanOnOff fan(m); + + WaterHeaterHeatPumpWrappedCondenser hpwh(m); + + hpwh.setName("My WaterHeaterHeatPumpWrappedCondenser"); + Schedule availabilitySchedule = m.alwaysOnDiscreteSchedule(); + EXPECT_TRUE(hpwh.setAvailabilitySchedule(availabilitySchedule)); + ScheduleConstant scheduleConstant1(m); + scheduleConstant1.setValue(0.1); + EXPECT_TRUE(hpwh.setCompressorSetpointTemperatureSchedule(scheduleConstant1)); + EXPECT_TRUE(hpwh.setDeadBandTemperatureDifference(1)); + EXPECT_TRUE(hpwh.setCondenserBottomLocation(2)); + EXPECT_TRUE(hpwh.setCondenserTopLocation(3)); + EXPECT_TRUE(hpwh.setEvaporatorAirFlowRate(4)); + EXPECT_TRUE(hpwh.setInletAirConfiguration("Schedule")); + ScheduleConstant scheduleConstant2(m); + scheduleConstant2.setValue(0.2); + EXPECT_TRUE(hpwh.setInletAirTemperatureSchedule(scheduleConstant2)); + ScheduleConstant scheduleConstant3(m); + scheduleConstant3.setValue(0.3); + EXPECT_TRUE(hpwh.setInletAirHumiditySchedule(scheduleConstant3)); + EXPECT_TRUE(hpwh.setTank(tank)); + EXPECT_TRUE(hpwh.setDXCoil(coil)); + EXPECT_TRUE(hpwh.setMinimumInletAirTemperatureforCompressorOperation(15)); + EXPECT_TRUE(hpwh.setMaximumInletAirTemperatureforCompressorOperation(30)); + EXPECT_TRUE(hpwh.setCompressorLocation("Outdoors")); + ScheduleConstant scheduleConstant4(m); + scheduleConstant4.setValue(0.4); + EXPECT_TRUE(hpwh.setCompressorAmbientTemperatureSchedule(scheduleConstant4)); + EXPECT_TRUE(hpwh.setFan(fan)); + EXPECT_TRUE(hpwh.setFanPlacement("DrawThrough")); + EXPECT_TRUE(hpwh.setOnCycleParasiticElectricLoad(40)); + EXPECT_TRUE(hpwh.setOffCycleParasiticElectricLoad(50)); + EXPECT_TRUE(hpwh.setParasiticHeatRejectionLocation("Zone")); + ScheduleConstant scheduleConstant5(m); + scheduleConstant5.setValue(0.5); + EXPECT_TRUE(hpwh.setInletAirMixerSchedule(scheduleConstant5)); + EXPECT_TRUE(hpwh.setTankElementControlLogic("Simultaneous")); + EXPECT_TRUE(hpwh.setControlSensor1HeightInStratifiedTank(60)); + EXPECT_TRUE(hpwh.setControlSensor1Weight(0.75)); + EXPECT_TRUE(hpwh.setControlSensor2HeightInStratifiedTank(70)); + + PlantLoop plant_loop(m); + + plant_loop.addSupplyBranchForComponent(tank); + + ForwardTranslator ft; + const Workspace w = ft.translateModel(m); + + const auto idfObjs = w.getObjectsByType(IddObjectType::WaterHeater_HeatPump_WrappedCondenser); + ASSERT_EQ(1u, idfObjs.size()); + const auto& idfObject = idfObjs.front(); + + EXPECT_EQ(hpwh.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::Name).get()); + EXPECT_EQ(availabilitySchedule.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::AvailabilityScheduleName).get()); + EXPECT_EQ(scheduleConstant1.nameString(), + idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::CompressorSetpointTemperatureScheduleName).get()); + EXPECT_EQ(1, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::DeadBandTemperatureDifference).get()); + EXPECT_EQ(2, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::CondenserBottomLocation).get()); + EXPECT_EQ(3, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::CondenserTopLocation).get()); + EXPECT_EQ(4, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::EvaporatorAirFlowRate).get()); + EXPECT_EQ("Schedule", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::InletAirConfiguration).get()); + EXPECT_EQ(hpwh.nameString() + " Inlet", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::AirInletNodeName).get()); + EXPECT_EQ(hpwh.nameString() + " Outlet", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::AirOutletNodeName).get()); + EXPECT_TRUE(idfObject.isEmpty(WaterHeater_HeatPump_WrappedCondenserFields::OutdoorAirNodeName)); + EXPECT_TRUE(idfObject.isEmpty(WaterHeater_HeatPump_WrappedCondenserFields::ExhaustAirNodeName)); + EXPECT_EQ(scheduleConstant2.nameString(), + idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::InletAirTemperatureScheduleName).get()); + EXPECT_EQ(scheduleConstant3.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::InletAirHumidityScheduleName).get()); + EXPECT_EQ(tz.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::InletAirZoneName).get()); + EXPECT_EQ("WaterHeater:Stratified", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::TankObjectType).get()); + EXPECT_EQ(tank.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::TankName).get()); + EXPECT_EQ(tank.supplyInletModelObject()->name().get(), + idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::TankUseSideInletNodeName).get()); + EXPECT_EQ(tank.supplyOutletModelObject()->name().get(), + idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::TankUseSideOutletNodeName).get()); + EXPECT_EQ("Coil:WaterHeating:AirToWaterHeatPump:Wrapped", + idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::DXCoilObjectType).get()); + EXPECT_EQ(coil.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::DXCoilName).get()); + EXPECT_EQ(15, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::MinimumInletAirTemperatureforCompressorOperation).get()); + EXPECT_EQ(30, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::MaximumInletAirTemperatureforCompressorOperation).get()); + EXPECT_EQ("Outdoors", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::CompressorLocation).get()); + EXPECT_EQ(scheduleConstant4.nameString(), + idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::CompressorAmbientTemperatureScheduleName).get()); + EXPECT_EQ("Fan:OnOff", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::FanObjectType).get()); + EXPECT_EQ(fan.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::FanName).get()); + EXPECT_EQ("DrawThrough", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::FanPlacement).get()); + EXPECT_EQ(40, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::OnCycleParasiticElectricLoad).get()); + EXPECT_EQ(50, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::OffCycleParasiticElectricLoad).get()); + EXPECT_EQ("Zone", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::ParasiticHeatRejectionLocation).get()); + EXPECT_TRUE(idfObject.isEmpty(WaterHeater_HeatPump_WrappedCondenserFields::InletAirMixerNodeName)); + EXPECT_TRUE(idfObject.isEmpty(WaterHeater_HeatPump_WrappedCondenserFields::OutletAirSplitterNodeName)); + EXPECT_EQ(scheduleConstant5.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::InletAirMixerScheduleName).get()); + EXPECT_EQ("Simultaneous", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::TankElementControlLogic).get()); + EXPECT_EQ(60, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::ControlSensor1HeightInStratifiedTank).get()); + EXPECT_EQ(0.75, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::ControlSensor1Weight).get()); + EXPECT_EQ(70, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::ControlSensor2HeightInStratifiedTank).get()); +} diff --git a/src/model/test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp b/src/model/test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp index de203012a45..b207ce3bdff 100644 --- a/src/model/test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp +++ b/src/model/test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp @@ -85,6 +85,20 @@ TEST_F(ModelFixture, WaterHeaterHeatPumpWrappedCondenser_GettersSetters) { EXPECT_FALSE(hpwh.setInletAirConfiguration("BADENUM")); EXPECT_EQ("OutdoorAirOnly", hpwh.inletAirConfiguration()); + // Air Inlet Node Name: Required String + EXPECT_EQ("", hpwh.airInletNodeName()); + EXPECT_TRUE(hpwh.setInletAirConfiguration("ZoneAirOnly")); + EXPECT_EQ("", hpwh.airInletNodeName()); + EXPECT_TRUE(hpwh.setInletAirConfiguration("Schedule")); + EXPECT_EQ(hpwh.nameString() + " Inlet", hpwh.airInletNodeName()); + + // Air Outlet Node Name: Required String + EXPECT_EQ("", hpwh.airOutletNodeName()); + EXPECT_TRUE(hpwh.setOutletAirConfiguration("ZoneAndOutdoorAir")); + EXPECT_EQ("", hpwh.airOutletNodeName()); + EXPECT_TRUE(hpwh.setOutletAirConfiguration("Schedule")); + EXPECT_EQ(hpwh.nameString() + " Outlet", hpwh.airOutletNodeName()); + // Inlet Air Temperature Schedule: Optional Object but set in Ctor { ScheduleConstant obj(m); From 67a0bb57396a1ec995bf6c3624b137678e573648 Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Mon, 15 Dec 2025 10:14:36 -0700 Subject: [PATCH 4/7] Clean up comments and tests. --- ...ateWaterHeaterHeatPumpWrappedCondenser.cpp | 36 ------------------- ...erHeaterHeatPumpWrappedCondenser_GTest.cpp | 14 +++----- ...erHeaterHeatPumpWrappedCondenser_GTest.cpp | 4 +-- 3 files changed, 7 insertions(+), 47 deletions(-) diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateWaterHeaterHeatPumpWrappedCondenser.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateWaterHeaterHeatPumpWrappedCondenser.cpp index 52543de3471..afea0fd33a6 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateWaterHeaterHeatPumpWrappedCondenser.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateWaterHeaterHeatPumpWrappedCondenser.cpp @@ -134,14 +134,6 @@ namespace energyplus { // This is helpful if you need to control this via EMS if (istringEqual(inletAirConfiguration, "ZoneAirOnly")) { if (auto thermalZone = modelObject.thermalZone()) { - // auto inletNode = modelObject.inletNode(); - // OS_ASSERT(inletNode); - // airInletNodeName = inletNode->name().get(); - - // auto outletNode = modelObject.outletNode(); - // OS_ASSERT(outletNode); - // airOutletNodeName = outletNode->name().get(); - inletAirZoneName = thermalZone->name().get(); fanInletNodeName = modelObject.name().get() + " Evap Outlet - Fan Inlet"; fanOutletNodeName = airOutletNodeName; @@ -150,14 +142,6 @@ namespace energyplus { } } else if (istringEqual(inletAirConfiguration, "ZoneAndOutdoorAir")) { if (auto thermalZone = modelObject.thermalZone()) { - // auto inletNode = modelObject.inletNode(); - // OS_ASSERT(inletNode); - // airInletNodeName = inletNode->name().get(); - - // auto outletNode = modelObject.outletNode(); - // OS_ASSERT(outletNode); - // airOutletNodeName = outletNode->name().get(); - outdoorAirNodeName = modelObject.name().get() + " Outdoor Air"; exhaustAirNodeName = modelObject.name().get() + " Exhaust Air"; inletAirZoneName = thermalZone->name().get(); @@ -176,8 +160,6 @@ namespace energyplus { evapInletNodeName = outdoorAirNodeName; evapOutletNodeName = fanInletNodeName; } else if (istringEqual(inletAirConfiguration, "Schedule")) { - // airInletNodeName = modelObject.name().get() + " Inlet"; - // airOutletNodeName = modelObject.name().get() + " Outlet"; fanInletNodeName = modelObject.name().get() + " Evap Outlet - Fan Inlet"; fanOutletNodeName = airOutletNodeName; evapInletNodeName = airInletNodeName; @@ -189,14 +171,6 @@ namespace energyplus { if (istringEqual(inletAirConfiguration, "ZoneAirOnly")) { if (auto thermalZone = modelObject.thermalZone()) { - // auto inletNode = modelObject.inletNode(); - // OS_ASSERT(inletNode); - // airInletNodeName = inletNode->name().get(); - - // auto outletNode = modelObject.outletNode(); - // OS_ASSERT(outletNode); - // airOutletNodeName = outletNode->name().get(); - inletAirZoneName = thermalZone->name().get(); fanInletNodeName = airInletNodeName; fanOutletNodeName = modelObject.name().get() + " Fan Outlet - Evap Inlet"; @@ -205,14 +179,6 @@ namespace energyplus { } } else if (istringEqual(inletAirConfiguration, "ZoneAndOutdoorAir")) { if (auto thermalZone = modelObject.thermalZone()) { - // auto inletNode = modelObject.inletNode(); - // OS_ASSERT(inletNode); - // airInletNodeName = inletNode->name().get(); - - // auto outletNode = modelObject.outletNode(); - // OS_ASSERT(outletNode); - // airOutletNodeName = outletNode->name().get(); - outdoorAirNodeName = modelObject.name().get() + " Outdoor Air"; exhaustAirNodeName = modelObject.name().get() + " Exhaust Air"; inletAirZoneName = thermalZone->name().get(); @@ -231,8 +197,6 @@ namespace energyplus { evapInletNodeName = fanOutletNodeName; evapOutletNodeName = exhaustAirNodeName; } else if (istringEqual(inletAirConfiguration, "Schedule")) { - // airInletNodeName = modelObject.name().get() + " Inlet"; - // airOutletNodeName = modelObject.name().get() + " Outlet"; fanInletNodeName = airInletNodeName; fanOutletNodeName = modelObject.name().get() + " Fan Outlet - Evap Inlet"; evapInletNodeName = fanOutletNodeName; diff --git a/src/energyplus/Test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp b/src/energyplus/Test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp index 8c0c7305241..930f23b199e 100644 --- a/src/energyplus/Test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp +++ b/src/energyplus/Test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp @@ -107,8 +107,7 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_WaterHeaterHeatPumpWrappedCondenser_ EXPECT_EQ(hpwh.outletNode()->nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::AirOutletNodeName).get()); EXPECT_TRUE(idfObject.isEmpty(WaterHeater_HeatPump_WrappedCondenserFields::OutdoorAirNodeName)); EXPECT_TRUE(idfObject.isEmpty(WaterHeater_HeatPump_WrappedCondenserFields::ExhaustAirNodeName)); - EXPECT_EQ(scheduleConstant2.nameString(), - idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::InletAirTemperatureScheduleName).get()); + EXPECT_EQ(scheduleConstant2.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::InletAirTemperatureScheduleName).get()); EXPECT_EQ(scheduleConstant3.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::InletAirHumidityScheduleName).get()); EXPECT_EQ(tz.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::InletAirZoneName).get()); EXPECT_EQ("WaterHeater:Stratified", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::TankObjectType).get()); @@ -117,8 +116,7 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_WaterHeaterHeatPumpWrappedCondenser_ idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::TankUseSideInletNodeName).get()); EXPECT_EQ(tank.supplyOutletModelObject()->name().get(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::TankUseSideOutletNodeName).get()); - EXPECT_EQ("Coil:WaterHeating:AirToWaterHeatPump:Wrapped", - idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::DXCoilObjectType).get()); + EXPECT_EQ("Coil:WaterHeating:AirToWaterHeatPump:Wrapped", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::DXCoilObjectType).get()); EXPECT_EQ(coil.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::DXCoilName).get()); EXPECT_EQ(15, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::MinimumInletAirTemperatureforCompressorOperation).get()); EXPECT_EQ(30, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::MaximumInletAirTemperatureforCompressorOperation).get()); @@ -210,18 +208,16 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_WaterHeaterHeatPumpWrappedCondenser_ EXPECT_EQ(hpwh.nameString() + " Outlet", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::AirOutletNodeName).get()); EXPECT_TRUE(idfObject.isEmpty(WaterHeater_HeatPump_WrappedCondenserFields::OutdoorAirNodeName)); EXPECT_TRUE(idfObject.isEmpty(WaterHeater_HeatPump_WrappedCondenserFields::ExhaustAirNodeName)); - EXPECT_EQ(scheduleConstant2.nameString(), - idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::InletAirTemperatureScheduleName).get()); + EXPECT_EQ(scheduleConstant2.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::InletAirTemperatureScheduleName).get()); EXPECT_EQ(scheduleConstant3.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::InletAirHumidityScheduleName).get()); - EXPECT_EQ(tz.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::InletAirZoneName).get()); + EXPECT_TRUE(idfObject.isEmpty(WaterHeater_HeatPump_WrappedCondenserFields::InletAirZoneName)); EXPECT_EQ("WaterHeater:Stratified", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::TankObjectType).get()); EXPECT_EQ(tank.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::TankName).get()); EXPECT_EQ(tank.supplyInletModelObject()->name().get(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::TankUseSideInletNodeName).get()); EXPECT_EQ(tank.supplyOutletModelObject()->name().get(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::TankUseSideOutletNodeName).get()); - EXPECT_EQ("Coil:WaterHeating:AirToWaterHeatPump:Wrapped", - idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::DXCoilObjectType).get()); + EXPECT_EQ("Coil:WaterHeating:AirToWaterHeatPump:Wrapped", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::DXCoilObjectType).get()); EXPECT_EQ(coil.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::DXCoilName).get()); EXPECT_EQ(15, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::MinimumInletAirTemperatureforCompressorOperation).get()); EXPECT_EQ(30, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::MaximumInletAirTemperatureforCompressorOperation).get()); diff --git a/src/model/test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp b/src/model/test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp index b207ce3bdff..c1f9e1f1299 100644 --- a/src/model/test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp +++ b/src/model/test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp @@ -94,9 +94,9 @@ TEST_F(ModelFixture, WaterHeaterHeatPumpWrappedCondenser_GettersSetters) { // Air Outlet Node Name: Required String EXPECT_EQ("", hpwh.airOutletNodeName()); - EXPECT_TRUE(hpwh.setOutletAirConfiguration("ZoneAndOutdoorAir")); + EXPECT_TRUE(hpwh.setInletAirConfiguration("ZoneAndOutdoorAir")); EXPECT_EQ("", hpwh.airOutletNodeName()); - EXPECT_TRUE(hpwh.setOutletAirConfiguration("Schedule")); + EXPECT_TRUE(hpwh.setInletAirConfiguration("Schedule")); EXPECT_EQ(hpwh.nameString() + " Outlet", hpwh.airOutletNodeName()); // Inlet Air Temperature Schedule: Optional Object but set in Ctor From 0c2ec6026c369c0393420be2cd2814b31b521a0f Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Mon, 15 Dec 2025 10:56:19 -0700 Subject: [PATCH 5/7] Try to fix tests. --- .../Test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp | 2 ++ src/model/test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/src/energyplus/Test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp b/src/energyplus/Test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp index 930f23b199e..53135d9e08e 100644 --- a/src/energyplus/Test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp +++ b/src/energyplus/Test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp @@ -88,6 +88,7 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_WaterHeaterHeatPumpWrappedCondenser_ ForwardTranslator ft; const Workspace w = ft.translateModel(m); + EXPECT_EQ(1u, w.getObjectsByType(IddObjectType::WaterHeater_Stratified).size()); const auto idfObjs = w.getObjectsByType(IddObjectType::WaterHeater_HeatPump_WrappedCondenser); ASSERT_EQ(1u, idfObjs.size()); const auto& idfObject = idfObjs.front(); @@ -191,6 +192,7 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_WaterHeaterHeatPumpWrappedCondenser_ ForwardTranslator ft; const Workspace w = ft.translateModel(m); + EXPECT_EQ(1u, w.getObjectsByType(IddObjectType::WaterHeater_Stratified).size()); const auto idfObjs = w.getObjectsByType(IddObjectType::WaterHeater_HeatPump_WrappedCondenser); ASSERT_EQ(1u, idfObjs.size()); const auto& idfObject = idfObjs.front(); diff --git a/src/model/test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp b/src/model/test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp index c1f9e1f1299..a9b133da6a9 100644 --- a/src/model/test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp +++ b/src/model/test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp @@ -89,10 +89,15 @@ TEST_F(ModelFixture, WaterHeaterHeatPumpWrappedCondenser_GettersSetters) { EXPECT_EQ("", hpwh.airInletNodeName()); EXPECT_TRUE(hpwh.setInletAirConfiguration("ZoneAirOnly")); EXPECT_EQ("", hpwh.airInletNodeName()); + EXPECT_TRUE(hpwh.setInletAirConfiguration("ZoneAndOutdoorAir")); + EXPECT_EQ("", hpwh.airInletNodeName()); EXPECT_TRUE(hpwh.setInletAirConfiguration("Schedule")); EXPECT_EQ(hpwh.nameString() + " Inlet", hpwh.airInletNodeName()); // Air Outlet Node Name: Required String + EXPECT_TRUE(hpwh.setInletAirConfiguration("OutdoorAirOnly")); + EXPECT_EQ("", hpwh.airOutletNodeName()); + EXPECT_TRUE(hpwh.setInletAirConfiguration("ZoneAirOnly")); EXPECT_EQ("", hpwh.airOutletNodeName()); EXPECT_TRUE(hpwh.setInletAirConfiguration("ZoneAndOutdoorAir")); EXPECT_EQ("", hpwh.airOutletNodeName()); From 1e551d74b9ebacefeeb99410c252a19c7e82832e Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Mon, 15 Dec 2025 11:55:54 -0700 Subject: [PATCH 6/7] More fixes to ft tests. --- ...erHeaterHeatPumpWrappedCondenser_GTest.cpp | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/energyplus/Test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp b/src/energyplus/Test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp index 53135d9e08e..c3ab1afe53a 100644 --- a/src/energyplus/Test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp +++ b/src/energyplus/Test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp @@ -85,6 +85,9 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_WaterHeaterHeatPumpWrappedCondenser_ EXPECT_TRUE(hpwh.addToThermalZone(tz)); + PlantLoop plant_loop(m); + EXPECT_TRUE(plant_loop.addSupplyBranchForComponent(tank)); + ForwardTranslator ft; const Workspace w = ft.translateModel(m); @@ -113,9 +116,11 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_WaterHeaterHeatPumpWrappedCondenser_ EXPECT_EQ(tz.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::InletAirZoneName).get()); EXPECT_EQ("WaterHeater:Stratified", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::TankObjectType).get()); EXPECT_EQ(tank.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::TankName).get()); - EXPECT_EQ(tank.supplyInletModelObject()->name().get(), + ASSERT_TRUE(tank.supplyInletModelObject()); + EXPECT_EQ(tank.supplyInletModelObject()->nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::TankUseSideInletNodeName).get()); - EXPECT_EQ(tank.supplyOutletModelObject()->name().get(), + ASSERT_TRUE(tank.supplyOutletModelObject()); + EXPECT_EQ(tank.supplyOutletModelObject()->nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::TankUseSideOutletNodeName).get()); EXPECT_EQ("Coil:WaterHeating:AirToWaterHeatPump:Wrapped", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::DXCoilObjectType).get()); EXPECT_EQ(coil.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::DXCoilName).get()); @@ -138,7 +143,7 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_WaterHeaterHeatPumpWrappedCondenser_ EXPECT_EQ(70, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::ControlSensor2HeightInStratifiedTank).get()); } -TEST_F(EnergyPlusFixture, ForwardTranslator_WaterHeaterHeatPumpWrappedCondenser_addSupplyBranchForComponent) { +TEST_F(EnergyPlusFixture, ForwardTranslator_WaterHeaterHeatPumpWrappedCondenser_Schedule) { Model m; WaterHeaterStratified tank(m); @@ -186,8 +191,7 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_WaterHeaterHeatPumpWrappedCondenser_ EXPECT_TRUE(hpwh.setControlSensor2HeightInStratifiedTank(70)); PlantLoop plant_loop(m); - - plant_loop.addSupplyBranchForComponent(tank); + EXPECT_TRUE(plant_loop.addSupplyBranchForComponent(tank)); ForwardTranslator ft; const Workspace w = ft.translateModel(m); @@ -215,17 +219,18 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_WaterHeaterHeatPumpWrappedCondenser_ EXPECT_TRUE(idfObject.isEmpty(WaterHeater_HeatPump_WrappedCondenserFields::InletAirZoneName)); EXPECT_EQ("WaterHeater:Stratified", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::TankObjectType).get()); EXPECT_EQ(tank.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::TankName).get()); - EXPECT_EQ(tank.supplyInletModelObject()->name().get(), + ASSERT_TRUE(tank.supplyInletModelObject()); + EXPECT_EQ(tank.supplyInletModelObject()->nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::TankUseSideInletNodeName).get()); - EXPECT_EQ(tank.supplyOutletModelObject()->name().get(), + ASSERT_TRUE(tank.supplyOutletModelObject()); + EXPECT_EQ(tank.supplyOutletModelObject()->nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::TankUseSideOutletNodeName).get()); EXPECT_EQ("Coil:WaterHeating:AirToWaterHeatPump:Wrapped", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::DXCoilObjectType).get()); EXPECT_EQ(coil.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::DXCoilName).get()); EXPECT_EQ(15, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::MinimumInletAirTemperatureforCompressorOperation).get()); EXPECT_EQ(30, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::MaximumInletAirTemperatureforCompressorOperation).get()); EXPECT_EQ("Outdoors", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::CompressorLocation).get()); - EXPECT_EQ(scheduleConstant4.nameString(), - idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::CompressorAmbientTemperatureScheduleName).get()); + EXPECT_TRUE(idfObject.isEmpty(WaterHeater_HeatPump_WrappedCondenserFields::CompressorAmbientTemperatureScheduleName)); EXPECT_EQ("Fan:OnOff", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::FanObjectType).get()); EXPECT_EQ(fan.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::FanName).get()); EXPECT_EQ("DrawThrough", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::FanPlacement).get()); From a520737331e59d35a5edccf314d344d00fca05fd Mon Sep 17 00:00:00 2001 From: Joe Robertson Date: Mon, 15 Dec 2025 11:59:32 -0700 Subject: [PATCH 7/7] Schedule compressor location for schedule test. --- .../Test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/energyplus/Test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp b/src/energyplus/Test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp index c3ab1afe53a..48ea66d0d53 100644 --- a/src/energyplus/Test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp +++ b/src/energyplus/Test/WaterHeaterHeatPumpWrappedCondenser_GTest.cpp @@ -173,7 +173,7 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_WaterHeaterHeatPumpWrappedCondenser_ EXPECT_TRUE(hpwh.setDXCoil(coil)); EXPECT_TRUE(hpwh.setMinimumInletAirTemperatureforCompressorOperation(15)); EXPECT_TRUE(hpwh.setMaximumInletAirTemperatureforCompressorOperation(30)); - EXPECT_TRUE(hpwh.setCompressorLocation("Outdoors")); + EXPECT_TRUE(hpwh.setCompressorLocation("Schedule")); ScheduleConstant scheduleConstant4(m); scheduleConstant4.setValue(0.4); EXPECT_TRUE(hpwh.setCompressorAmbientTemperatureSchedule(scheduleConstant4)); @@ -229,8 +229,9 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_WaterHeaterHeatPumpWrappedCondenser_ EXPECT_EQ(coil.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::DXCoilName).get()); EXPECT_EQ(15, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::MinimumInletAirTemperatureforCompressorOperation).get()); EXPECT_EQ(30, idfObject.getDouble(WaterHeater_HeatPump_WrappedCondenserFields::MaximumInletAirTemperatureforCompressorOperation).get()); - EXPECT_EQ("Outdoors", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::CompressorLocation).get()); - EXPECT_TRUE(idfObject.isEmpty(WaterHeater_HeatPump_WrappedCondenserFields::CompressorAmbientTemperatureScheduleName)); + EXPECT_EQ("Schedule", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::CompressorLocation).get()); + EXPECT_EQ(scheduleConstant4.nameString(), + idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::CompressorAmbientTemperatureScheduleName).get()); EXPECT_EQ("Fan:OnOff", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::FanObjectType).get()); EXPECT_EQ(fan.nameString(), idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::FanName).get()); EXPECT_EQ("DrawThrough", idfObject.getString(WaterHeater_HeatPump_WrappedCondenserFields::FanPlacement).get());