diff --git a/resources/model/OpenStudio.idd b/resources/model/OpenStudio.idd index 9e458b4926..399fff8db7 100644 --- a/resources/model/OpenStudio.idd +++ b/resources/model/OpenStudio.idd @@ -31809,7 +31809,22 @@ OS:ZoneHVAC:Baseboard:RadiantConvective:Water, \type real \minimum 0 \maximum 1 - N2; \field Fraction of Radiant Energy Incident on People + N2, \field Fraction of Radiant Energy Incident on People + \required-field + \type real + \minimum 0 + \maximum 1 + N3, \field Fraction of Radiant Energy to Floor Surfaces + \required-field + \type real + \minimum 0 + \maximum 1 + N4, \field Fraction of Radiant Energy to Wall Surfaces + \required-field + \type real + \minimum 0 + \maximum 1 + N5; \field Fraction of Radiant Energy to Ceiling Surfaces \required-field \type real \minimum 0 @@ -31857,34 +31872,64 @@ OS:ZoneHVAC:Baseboard:RadiantConvective:Electric, \type real \minimum 0 \maximum 1 - N6; \field Fraction of Radiant Energy Incident on People + N6, \field Fraction of Radiant Energy Incident on People + \required-field + \type real + \minimum 0 + \maximum 1 + N7, \field Fraction of Radiant Energy to Floor Surfaces + \required-field + \type real + \minimum 0 + \maximum 1 + N8, \field Fraction of Radiant Energy to Wall Surfaces + \required-field + \type real + \minimum 0 + \maximum 1 + N9; \field Fraction of Radiant Energy to Ceiling Surfaces \required-field \type real \minimum 0 \maximum 1 OS:ZoneHVAC:CoolingPanel:RadiantConvective:Water, - A1 , \field Handle + A1, \field Handle \type handle \required-field - A2 , \field Name + A2, \field Name \required-field \type alpha \reference ConnectionObject - A3 , \field Availability Schedule Name + A3, \field Availability Schedule Name \required-field \type object-list \object-list ScheduleNames - A4 , \field Cooling Coil Name + A4, \field Cooling Coil Name \type object-list \required-field \object-list RadiantPanelCoolingCoil - N1 , \field Fraction Radiant + N1, \field Fraction Radiant + \required-field + \type real + \minimum 0 + \maximum 1 + N2, \field Fraction of Radiant Energy Incident on People + \required-field + \type real + \minimum 0 + \maximum 1 + N3, \field Fraction of Radiant Energy to Floor Surfaces + \required-field + \type real + \minimum 0 + \maximum 1 + N4, \field Fraction of Radiant Energy to Wall Surfaces \required-field \type real \minimum 0 \maximum 1 - N2 ; \field Fraction of Radiant Energy Incident on People + N5; \field Fraction of Radiant Energy to Ceiling Surfaces \required-field \type real \minimum 0 diff --git a/src/energyplus/CMakeLists.txt b/src/energyplus/CMakeLists.txt index 306cb07c83..fe3a71d9f7 100644 --- a/src/energyplus/CMakeLists.txt +++ b/src/energyplus/CMakeLists.txt @@ -862,7 +862,9 @@ set(${target_name}_test_src Test/WaterHeaterStratified_GTest.cpp Test/WaterUseConnections_GTest.cpp Test/ZoneAirHeatBalanceAlgorithm_GTest.cpp + Test/ZoneHVACBaseboardRadiantConvectiveElectric_GTest.cpp Test/ZoneHVACBaseboardRadiantConvectiveWater_GTest.cpp + Test/ZoneHVACCoolingPanelRadiantConvectiveWater_GTest.cpp Test/ZoneHVACEvaporativeCoolerUnit_GTest.cpp Test/ZoneHVACIdealLoadsAirSystem_GTest.cpp Test/ZoneHVACLowTemperatureRadiantElectric_GTest.cpp diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACBaseboardRadiantConvectiveElectric.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACBaseboardRadiantConvectiveElectric.cpp index 5f05f9218c..e8e32012ab 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACBaseboardRadiantConvectiveElectric.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACBaseboardRadiantConvectiveElectric.cpp @@ -110,12 +110,15 @@ namespace energyplus { } } - // Assume that 5% of what is not on people is on the floor - double fractionOnFloor = (1.0 - fractionofRadiantEnergyIncidentonPeople) * 0.05; - // Assume that 55% of what is not on people is on the walls - double fractionOnWall = (1.0 - fractionofRadiantEnergyIncidentonPeople) * 0.55; - // Assume that 40% of what is not on people is on the ceiling - double fractionOnCeiling = (1.0 - fractionofRadiantEnergyIncidentonPeople) * 0.40; + // SurfaceName + // FractionofRadiantEnergytoSurface + double fractionofRadiantEnergytoFloorSurfaces = modelObject.fractionofRadiantEnergytoFloorSurfaces(); + double fractionofRadiantEnergytoWallSurfaces = modelObject.fractionofRadiantEnergytoWallSurfaces(); + double fractionofRadiantEnergytoCeilingSurfaces = modelObject.fractionofRadiantEnergytoCeilingSurfaces(); + + double fractionOnFloor = (1.0 - fractionofRadiantEnergyIncidentonPeople) * fractionofRadiantEnergytoFloorSurfaces; + double fractionOnWall = (1.0 - fractionofRadiantEnergyIncidentonPeople) * fractionofRadiantEnergytoWallSurfaces; + double fractionOnCeiling = (1.0 - fractionofRadiantEnergyIncidentonPeople) * fractionofRadiantEnergytoCeilingSurfaces; //loop through all the surfaces, adding them and their flow fractions (weighted per-area) for (auto const& surface : surfaces) { IdfExtensibleGroup group = idfObject.pushExtensibleGroup(); diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACBaseboardRadiantConvectiveWater.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACBaseboardRadiantConvectiveWater.cpp index 9f4d50a41a..8e325dc414 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACBaseboardRadiantConvectiveWater.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACBaseboardRadiantConvectiveWater.cpp @@ -153,12 +153,15 @@ namespace energyplus { } } - // Assume that 5% of what is not on people is on the floor - double fractionOnFloor = (1.0 - fractionofRadiantEnergyIncidentonPeople) * 0.05; - // Assume that 55% of what is not on people is on the walls - double fractionOnWall = (1.0 - fractionofRadiantEnergyIncidentonPeople) * 0.55; - // Assume that 40% of what is not on people is on the ceiling - double fractionOnCeiling = (1.0 - fractionofRadiantEnergyIncidentonPeople) * 0.40; + // SurfaceName + // FractionofRadiantEnergytoSurface + double fractionofRadiantEnergytoFloorSurfaces = modelObject.fractionofRadiantEnergytoFloorSurfaces(); + double fractionofRadiantEnergytoWallSurfaces = modelObject.fractionofRadiantEnergytoWallSurfaces(); + double fractionofRadiantEnergytoCeilingSurfaces = modelObject.fractionofRadiantEnergytoCeilingSurfaces(); + + double fractionOnFloor = (1.0 - fractionofRadiantEnergyIncidentonPeople) * fractionofRadiantEnergytoFloorSurfaces; + double fractionOnWall = (1.0 - fractionofRadiantEnergyIncidentonPeople) * fractionofRadiantEnergytoWallSurfaces; + double fractionOnCeiling = (1.0 - fractionofRadiantEnergyIncidentonPeople) * fractionofRadiantEnergytoCeilingSurfaces; //loop through all the surfaces, adding them and their flow fractions (weighted per-area) for (auto const& surface : surfaces) { IdfExtensibleGroup group = idfObject.pushExtensibleGroup(); diff --git a/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACCoolingPanelRadiantConvectiveWater.cpp b/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACCoolingPanelRadiantConvectiveWater.cpp index d2b2d3c3e3..a619be3b80 100644 --- a/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACCoolingPanelRadiantConvectiveWater.cpp +++ b/src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACCoolingPanelRadiantConvectiveWater.cpp @@ -167,12 +167,15 @@ namespace energyplus { } } - // Assume that 5% of what is not on people is on the floor - double fractionOnFloor = (1.0 - fractionofRadiantEnergyIncidentonPeople) * 0.05; - // Assume that 55% of what is not on people is on the walls - double fractionOnWall = (1.0 - fractionofRadiantEnergyIncidentonPeople) * 0.55; - // Assume that 40% of what is not on people is on the ceiling - double fractionOnCeiling = (1.0 - fractionofRadiantEnergyIncidentonPeople) * 0.40; + // SurfaceName + // FractionofRadiantEnergytoSurface + double fractionofRadiantEnergytoFloorSurfaces = modelObject.fractionofRadiantEnergytoFloorSurfaces(); + double fractionofRadiantEnergytoWallSurfaces = modelObject.fractionofRadiantEnergytoWallSurfaces(); + double fractionofRadiantEnergytoCeilingSurfaces = modelObject.fractionofRadiantEnergytoCeilingSurfaces(); + + double fractionOnFloor = (1.0 - fractionofRadiantEnergyIncidentonPeople) * fractionofRadiantEnergytoFloorSurfaces; + double fractionOnWall = (1.0 - fractionofRadiantEnergyIncidentonPeople) * fractionofRadiantEnergytoWallSurfaces; + double fractionOnCeiling = (1.0 - fractionofRadiantEnergyIncidentonPeople) * fractionofRadiantEnergytoCeilingSurfaces; //loop through all the surfaces, adding them and their flow fractions (weighted per-area) for (auto const& surface : surfaces) { IdfExtensibleGroup group = idfObject.pushExtensibleGroup(); diff --git a/src/energyplus/Test/ZoneHVACBaseboardRadiantConvectiveElectric_GTest.cpp b/src/energyplus/Test/ZoneHVACBaseboardRadiantConvectiveElectric_GTest.cpp new file mode 100644 index 0000000000..d164d035bb --- /dev/null +++ b/src/energyplus/Test/ZoneHVACBaseboardRadiantConvectiveElectric_GTest.cpp @@ -0,0 +1,131 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) Alliance for Energy Innovation, LLC. +* See also https://openstudio.net/license +***********************************************************************************************************************/ + +#include +#include "EnergyPlusFixture.hpp" + +#include "../ForwardTranslator.hpp" +#include "../ReverseTranslator.hpp" + +#include "../../model/ZoneHVACBaseboardRadiantConvectiveElectric.hpp" +#include "../../model/ZoneHVACBaseboardRadiantConvectiveElectric_Impl.hpp" + +#include "../../model/Model.hpp" +#include "../../model/HVACComponent.hpp" +#include "../../model/ThermalZone.hpp" +#include "../../model/Space.hpp" +#include "../../model/Surface.hpp" +#include "../../model/Schedule.hpp" + +#include "../../utilities/idf/IdfFile.hpp" +#include "../../utilities/idf/Workspace.hpp" +#include "../../utilities/idf/IdfObject.hpp" +#include "../../utilities/idf/WorkspaceObject.hpp" +#include "../../utilities/geometry/Point3d.hpp" + +#include +#include + +using namespace openstudio::energyplus; +using namespace openstudio::model; +using namespace openstudio; + +TEST_F(EnergyPlusFixture, ZoneHVACBaseboardRadiantConvectiveElectric) { + //make the example model + Model m = model::exampleModel(); + + ZoneHVACBaseboardRadiantConvectiveElectric baseboard(m); + + Point3dVector floorPrint{ + {0, 10, 0}, + {10, 10, 0}, + {10, 0, 0}, + {0, 0, 0}, + }; + boost::optional space1 = Space::fromFloorPrint(floorPrint, 3, m); + ASSERT_TRUE(space1); + auto surfaces = space1->surfaces(); + EXPECT_EQ(6u, surfaces.size()); + + // Space needs to be in a ThermalZone or it's not translated + ThermalZone z(m); + EXPECT_TRUE(space1->setThermalZone(z)); + + EXPECT_TRUE(baseboard.addToThermalZone(z)); + + // Some tweaks to disambiguate the ft tests later + baseboard.setName("My Baseboard"); + EXPECT_TRUE(baseboard.setHeatingDesignCapacityMethod("CapacityPerFloorArea")); + EXPECT_TRUE(baseboard.setHeatingDesignCapacity(0)); + EXPECT_TRUE(baseboard.setHeatingDesignCapacityPerFloorArea(100.0)); + EXPECT_TRUE(baseboard.setFractionofAutosizedHeatingDesignCapacity(0)); + EXPECT_TRUE(baseboard.setEfficiency(0.9)); + EXPECT_TRUE(baseboard.setFractionRadiant(0.4)); + EXPECT_TRUE(baseboard.setFractionofRadiantEnergyIncidentonPeople(0.35)); + EXPECT_TRUE(baseboard.setFractionofRadiantEnergytoFloorSurfaces(0.41)); + EXPECT_TRUE(baseboard.setFractionofRadiantEnergytoWallSurfaces(0.51)); + EXPECT_TRUE(baseboard.setFractionofRadiantEnergytoCeilingSurfaces(0.61)); + + // Translate + ForwardTranslator ft; + Workspace w = ft.translateModel(m); + + WorkspaceObjectVector idfBaseboards = w.getObjectsByType(IddObjectType::ZoneHVAC_Baseboard_RadiantConvective_Electric); + ASSERT_EQ(1u, idfBaseboards.size()); + WorkspaceObject idfBaseboard(idfBaseboards[0]); + + // Name + EXPECT_EQ(baseboard.nameString(), idfBaseboard.getString(ZoneHVAC_Baseboard_RadiantConvective_ElectricFields::Name).get()); + // Availability Schedule Name + EXPECT_EQ(baseboard.availabilitySchedule().nameString(), + idfBaseboard.getString(ZoneHVAC_Baseboard_RadiantConvective_ElectricFields::AvailabilityScheduleName).get()); + // Heating Design Capacity Method + EXPECT_EQ("CapacityPerFloorArea", idfBaseboard.getString(ZoneHVAC_Baseboard_RadiantConvective_ElectricFields::HeatingDesignCapacityMethod).get()); + // Heating Design Capacity + EXPECT_TRUE(0.0, idfBaseboard.getString(ZoneHVAC_Baseboard_RadiantConvective_ElectricFields::HeatingDesignCapacity).get()); + // Heating Design Capacity Per Floor Area + EXPECT_EQ(100.0, idfBaseboard.getDouble(ZoneHVAC_Baseboard_RadiantConvective_ElectricFields::HeatingDesignCapacityPerFloorArea).get()); + // Fraction of Autosized Heating Design Capacity + EXPECT_EQ(0.0, idfBaseboard.getDouble(ZoneHVAC_Baseboard_RadiantConvective_ElectricFields::FractionofAutosizedHeatingDesignCapacity).get()); + // Efficiency + EXPECT_EQ(0.9, idfBaseboard.getDouble(ZoneHVAC_Baseboard_RadiantConvective_ElectricFields::Efficiency).get()); + // Fraction Radiant + EXPECT_EQ(0.4, idfBaseboard.getDouble(ZoneHVAC_Baseboard_RadiantConvective_ElectricFields::FractionRadiant).get()); + // Fraction of Radiant Energy Incident on People + EXPECT_EQ(0.35, idfBaseboard.getDouble(ZoneHVAC_Baseboard_RadiantConvective_ElectricFields::FractionofRadiantEnergyIncidentonPeople).get()); + + double totalAreaOfWallSurfaces = 0; + double totalAreaOfCeilingSurfaces = 0; + double totalAreaOfFloorSurfaces = 0; + + for (auto const& surface : surfaces) { + if (istringEqual(surface.surfaceType(), "Floor")) { + totalAreaOfFloorSurfaces += surface.grossArea(); + } else if (istringEqual(surface.surfaceType(), "RoofCeiling")) { + totalAreaOfCeilingSurfaces += surface.grossArea(); + } else { + totalAreaOfWallSurfaces += surface.grossArea(); + } + } + + // Surface 1 Name + // Fraction of Radiant Energy to Surface 1 + EXPECT_EQ(surfaces.size(), idfBaseboard.numExtensibleGroups()); + for (const auto& idf_eg : idfBaseboard.extensibleGroups()) { + const auto& surface = surfaces[idf_eg.groupIndex()]; + + EXPECT_EQ(surface.nameString(), idf_eg.getDouble(ZoneHVAC_Baseboard_RadiantConvective_ElectricExtensibleFields::SurfaceName).get()); + if (istringEqual(surface.surfaceType(), "Floor")) { + EXPECT_EQ(surface.grossArea() / totalAreaOfFloorSurfaces * 0.41, + idf_eg.getString(ZoneHVAC_Baseboard_RadiantConvective_ElectricExtensibleFields::FractionofRadiantEnergytoSurface).get()); + } else if (istringEqual(surface.surfaceType(), "RoofCeiling")) { + EXPECT_EQ(surface.grossArea() / totalAreaOfCeilingSurfaces * 0.61, + idf_eg.getString(ZoneHVAC_Baseboard_RadiantConvective_ElectricExtensibleFields::FractionofRadiantEnergytoSurface).get()); + } else { + EXPECT_EQ(surface.grossArea() / totalAreaOfWallSurfaces * 0.51, + idf_eg.getString(ZoneHVAC_Baseboard_RadiantConvective_ElectricExtensibleFields::FractionofRadiantEnergytoSurface).get()); + } + } +} diff --git a/src/energyplus/Test/ZoneHVACBaseboardRadiantConvectiveWater_GTest.cpp b/src/energyplus/Test/ZoneHVACBaseboardRadiantConvectiveWater_GTest.cpp index f2828056aa..d8933475d4 100644 --- a/src/energyplus/Test/ZoneHVACBaseboardRadiantConvectiveWater_GTest.cpp +++ b/src/energyplus/Test/ZoneHVACBaseboardRadiantConvectiveWater_GTest.cpp @@ -21,7 +21,6 @@ #include "../../model/Space.hpp" #include "../../model/Surface.hpp" #include "../../model/Schedule.hpp" -#include "../../utilities/geometry/Point3d.hpp" #include "../../utilities/idf/IdfFile.hpp" #include "../../utilities/idf/Workspace.hpp" @@ -68,7 +67,17 @@ TEST_F(EnergyPlusFixture, ZoneHVACBaseboardRadiantConvectiveWater) { baseboard.setName("My Baseboard"); EXPECT_TRUE(baseboard.setFractionRadiant(0.4)); EXPECT_TRUE(baseboard.setFractionofRadiantEnergyIncidentonPeople(0.3)); - EXPECT_TRUE(coil.setMaximumWaterFlowRate(1.0)); + EXPECT_TRUE(baseboard.setFractionofRadiantEnergytoFloorSurfaces(0.42)); + EXPECT_TRUE(baseboard.setFractionofRadiantEnergytoWallSurfaces(0.52)); + EXPECT_TRUE(baseboard.setFractionofRadiantEnergytoCeilingSurfaces(0.62)); + EXPECT_TRUE(coil.setRatedAverageWaterTemperature(25.0)); + EXPECT_TRUE(coil.setRatedWaterMassFlowRate(1.0)); + EXPECT_TRUE(coil.setHeatingDesignCapacityMethod("CapacityPerFloorArea")); + EXPECT_TRUE(coil.setHeatingDesignCapacity(0)); + EXPECT_TRUE(coil.setHeatingDesignCapacityPerFloorArea(2.0)); + EXPECT_TRUE(coil.setFractionofAutosizedHeatingDesignCapacity(0)); + EXPECT_TRUE(coil.setMaximumWaterFlowRate(3.0)); + EXPECT_TRUE(coil.setConvergenceTolerance(4.0)); // Translate ForwardTranslator ft; @@ -86,23 +95,17 @@ TEST_F(EnergyPlusFixture, ZoneHVACBaseboardRadiantConvectiveWater) { EXPECT_EQ(baseboard.availabilitySchedule().nameString(), idfBaseboard.getString(ZoneHVAC_Baseboard_RadiantConvective_WaterFields::AvailabilityScheduleName).get()); // Inlet Node Name - EXPECT_FALSE(idfBaseboard.getString(ZoneHVAC_Baseboard_RadiantConvective_WaterFields::InletNodeName).get().empty()); + EXPECT_FALSE(idfBaseboard.isEmpty(ZoneHVAC_Baseboard_RadiantConvective_WaterFields::InletNodeName)); // Outlet Node Name - EXPECT_FALSE(idfBaseboard.getString(ZoneHVAC_Baseboard_RadiantConvective_WaterFields::OutletNodeName).get().empty()); + EXPECT_FALSE(idfBaseboard.isEmpty(ZoneHVAC_Baseboard_RadiantConvective_WaterFields::OutletNodeName)); // Rated Average Water Temperature - EXPECT_EQ(coil.ratedAverageWaterTemperature(), - idfBaseboard.getDouble(ZoneHVAC_Baseboard_RadiantConvective_WaterFields::RatedAverageWaterTemperature).get()); + EXPECT_EQ(25.0, idfBaseboard.getDouble(ZoneHVAC_Baseboard_RadiantConvective_WaterFields::RatedAverageWaterTemperature).get()); // Rated Water Mass Flow Rate - EXPECT_EQ(coil.ratedWaterMassFlowRate(), idfBaseboard.getDouble(ZoneHVAC_Baseboard_RadiantConvective_WaterFields::RatedWaterMassFlowRate).get()); + EXPECT_EQ(1.0, idfBaseboard.getDouble(ZoneHVAC_Baseboard_RadiantConvective_WaterFields::RatedWaterMassFlowRate).get()); // Heating Design Capacity - EXPECT_TRUE( - openstudio::istringEqual("autosize", idfBaseboard.getString(ZoneHVAC_Baseboard_RadiantConvective_WaterFields::HeatingDesignCapacity).get())); + EXPECT_TRUE(0.0, idfBaseboard.getDouble(ZoneHVAC_Baseboard_RadiantConvective_WaterFields::HeatingDesignCapacity).get())); // Maximum Water Flow Rate - EXPECT_EQ(coil.maximumWaterFlowRate().get(), idfBaseboard.getDouble(ZoneHVAC_Baseboard_RadiantConvective_WaterFields::MaximumWaterFlowRate).get()); - - // Surface 1 Name - // Fraction of Radiant Energy to Surface 1 - EXPECT_EQ(surfaces.size(), idfBaseboard.numExtensibleGroups()); + EXPECT_EQ(3.0, idfBaseboard.getDouble(ZoneHVAC_Baseboard_RadiantConvective_WaterFields::MaximumWaterFlowRate).get()); // We check that it does have a design object assigned ASSERT_TRUE(idfBaseboard.getTarget(ZoneHVAC_Baseboard_RadiantConvective_WaterFields::DesignObject)); @@ -110,19 +113,48 @@ TEST_F(EnergyPlusFixture, ZoneHVACBaseboardRadiantConvectiveWater) { // Name EXPECT_EQ("My Baseboard Design", idfDesign.nameString()); // Heating Design Capacity Method - EXPECT_EQ(coil.heatingDesignCapacityMethod(), - idfDesign.getString(ZoneHVAC_Baseboard_RadiantConvective_Water_DesignFields::HeatingDesignCapacityMethod).get()); + EXPECT_EQ("CapacityPerFloorArea", idfDesign.getString(ZoneHVAC_Baseboard_RadiantConvective_Water_DesignFields::HeatingDesignCapacityMethod).get()); // Heating Design Capacity Per Floor Area - EXPECT_EQ(coil.heatingDesignCapacityPerFloorArea(), - idfDesign.getDouble(ZoneHVAC_Baseboard_RadiantConvective_Water_DesignFields::HeatingDesignCapacityPerFloorArea).get()); + EXPECT_EQ(2.0, idfDesign.getDouble(ZoneHVAC_Baseboard_RadiantConvective_Water_DesignFields::HeatingDesignCapacityPerFloorArea).get()); // Fraction of Autosized Heating Design Capacity - EXPECT_EQ(coil.fractionofAutosizedHeatingDesignCapacity(), - idfDesign.getDouble(ZoneHVAC_Baseboard_RadiantConvective_Water_DesignFields::FractionofAutosizedHeatingDesignCapacity).get()); + EXPECT_EQ(0.0, idfDesign.getDouble(ZoneHVAC_Baseboard_RadiantConvective_Water_DesignFields::FractionofAutosizedHeatingDesignCapacity).get()); // Convergence Tolerance - EXPECT_EQ(coil.convergenceTolerance(), idfDesign.getDouble(ZoneHVAC_Baseboard_RadiantConvective_Water_DesignFields::ConvergenceTolerance).get()); + EXPECT_EQ(4.0, idfDesign.getDouble(ZoneHVAC_Baseboard_RadiantConvective_Water_DesignFields::ConvergenceTolerance).get()); // Fraction Radiant - EXPECT_EQ(baseboard.fractionRadiant(), idfDesign.getDouble(ZoneHVAC_Baseboard_RadiantConvective_Water_DesignFields::FractionRadiant).get()); + EXPECT_EQ(0.4, idfDesign.getDouble(ZoneHVAC_Baseboard_RadiantConvective_Water_DesignFields::FractionRadiant).get()); // Fraction of Radiant Energy Incident on People - EXPECT_EQ(baseboard.fractionofRadiantEnergyIncidentonPeople(), - idfDesign.getDouble(ZoneHVAC_Baseboard_RadiantConvective_Water_DesignFields::FractionofRadiantEnergyIncidentonPeople).get()); + EXPECT_EQ(0.3, idfDesign.getDouble(ZoneHVAC_Baseboard_RadiantConvective_Water_DesignFields::FractionofRadiantEnergyIncidentonPeople).get()); + + double totalAreaOfWallSurfaces = 0; + double totalAreaOfCeilingSurfaces = 0; + double totalAreaOfFloorSurfaces = 0; + + for (auto const& surface : surfaces) { + if (istringEqual(surface.surfaceType(), "Floor")) { + totalAreaOfFloorSurfaces += surface.grossArea(); + } else if (istringEqual(surface.surfaceType(), "RoofCeiling")) { + totalAreaOfCeilingSurfaces += surface.grossArea(); + } else { + totalAreaOfWallSurfaces += surface.grossArea(); + } + } + + // Surface 1 Name + // Fraction of Radiant Energy to Surface 1 + EXPECT_EQ(surfaces.size(), idfBaseboard.numExtensibleGroups()); + for (const auto& idf_eg : idfBaseboard.extensibleGroups()) { + const auto& surface = surfaces[idf_eg.groupIndex()]; + + EXPECT_EQ(surface.nameString(), idf_eg.getDouble(ZoneHVAC_Baseboard_RadiantConvective_ElectricExtensibleFields::SurfaceName).get()); + if (istringEqual(surface.surfaceType(), "Floor")) { + EXPECT_EQ(surface.grossArea() / totalAreaOfFloorSurfaces * 0.42, + idf_eg.getString(ZoneHVAC_Baseboard_RadiantConvective_ElectricExtensibleFields::FractionofRadiantEnergytoSurface).get()); + } else if (istringEqual(surface.surfaceType(), "RoofCeiling")) { + EXPECT_EQ(surface.grossArea() / totalAreaOfCeilingSurfaces * 0.62, + idf_eg.getString(ZoneHVAC_Baseboard_RadiantConvective_ElectricExtensibleFields::FractionofRadiantEnergytoSurface).get()); + } else { + EXPECT_EQ(surface.grossArea() / totalAreaOfWallSurfaces * 0.52, + idf_eg.getString(ZoneHVAC_Baseboard_RadiantConvective_ElectricExtensibleFields::FractionofRadiantEnergytoSurface).get()); + } + } } diff --git a/src/energyplus/Test/ZoneHVACCoolingPanelRadiantConvectiveWater_GTest.cpp b/src/energyplus/Test/ZoneHVACCoolingPanelRadiantConvectiveWater_GTest.cpp new file mode 100644 index 0000000000..6a28ef187e --- /dev/null +++ b/src/energyplus/Test/ZoneHVACCoolingPanelRadiantConvectiveWater_GTest.cpp @@ -0,0 +1,170 @@ +/*********************************************************************************************************************** +* OpenStudio(R), Copyright (c) Alliance for Energy Innovation, LLC. +* See also https://openstudio.net/license +***********************************************************************************************************************/ + +#include +#include "EnergyPlusFixture.hpp" + +#include "../ForwardTranslator.hpp" +#include "../ReverseTranslator.hpp" + +#include "../../model/ZoneHVACCoolingPanelRadiantConvectiveWater.hpp" +#include "../../model/ZoneHVACCoolingPanelRadiantConvectiveWater_Impl.hpp" +#include "../../model/CoilCoolingWaterPanelRadiant.hpp" +#include "../../model/CoilCoolingWaterPanelRadiant_Impl.hpp" + +#include "../../model/Model.hpp" +#include "../../model/HVACComponent.hpp" +#include "../../model/PlantLoop.hpp" +#include "../../model/ThermalZone.hpp" +#include "../../model/Space.hpp" +#include "../../model/Surface.hpp" +#include "../../model/Schedule.hpp" +#include "../../model/ScheduleConstant.hpp" + +#include "../../utilities/idf/IdfFile.hpp" +#include "../../utilities/idf/Workspace.hpp" +#include "../../utilities/idf/IdfObject.hpp" +#include "../../utilities/idf/WorkspaceObject.hpp" +#include "../../utilities/geometry/Point3d.hpp" + +#include +#include + +using namespace openstudio::energyplus; +using namespace openstudio::model; +using namespace openstudio; + +TEST_F(EnergyPlusFixture, ZoneHVACCoolingPanelRadiantConvectiveWater) { + //make the example model + Model m = model::exampleModel(); + + ZoneHVACCoolingPanelRadiantConvectiveWater panel(m); + auto coil = panel.coolingCoil().cast(); + + PlantLoop p(m); + EXPECT_TRUE(p.addDemandBranchForComponent(coil)); + + Point3dVector floorPrint{ + {0, 10, 0}, + {10, 10, 0}, + {10, 0, 0}, + {0, 0, 0}, + }; + boost::optional space1 = Space::fromFloorPrint(floorPrint, 3, m); + ASSERT_TRUE(space1); + auto surfaces = space1->surfaces(); + EXPECT_EQ(6u, surfaces.size()); + + // Space needs to be in a ThermalZone or it's not translated + ThermalZone z(m); + EXPECT_TRUE(space1->setThermalZone(z)); + + EXPECT_TRUE(panel.addToThermalZone(z)); + + // Some tweaks to disambiguate the ft tests later + panel.setName("My Panel"); + EXPECT_TRUE(panel.setFractionRadiant(0.4)); + EXPECT_TRUE(panel.setFractionofRadiantEnergyIncidentonPeople(0.3)); + EXPECT_TRUE(panel.setFractionofRadiantEnergytoFloorSurfaces(0.43)); + EXPECT_TRUE(panel.setFractionofRadiantEnergytoWallSurfaces(0.53)); + EXPECT_TRUE(panel.setFractionofRadiantEnergytoCeilingSurfaces(0.63)); + EXPECT_TRUE(coil.setRatedInletWaterTemperature(1.0)); + EXPECT_TRUE(coil.setRatedInletSpaceTemperature(2.0)); + EXPECT_TRUE(coil.setRatedWaterMassFlowRate(3.0)); + EXPECT_TRUE(coil.setCoolingDesignCapacityMethod("FractionOfAutosizedCoolingCapacity")); + EXPECT_TRUE(coil.setCoolingDesignCapacity(0)); + EXPECT_TRUE(coil.setCoolingDesignCapacityPerFloorArea(0)); + EXPECT_TRUE(coil.setFractionofAutosizedCoolingDesignCapacity(4.0)); + EXPECT_TRUE(coil.setMaximumChilledWaterFlowRate(5.0)); + EXPECT_TRUE(coil.setControlType("OutdoorDryBulbTemperature")); + EXPECT_TRUE(coil.setCoolingControlThrottlingRange(6.0)); + ScheduleConstant coolingControlTemperatureSchedule(m); + EXPECT_TRUE(coil.setCoolingControlTemperatureSchedule(coolingControlTemperatureSchedule)); + EXPECT_TRUE(coil.setCondensationControlType("SimpleOff")); + EXPECT_TRUE(coil.setCondensationControlDewpointOffset(7.0)); + + // Translate + ForwardTranslator ft; + Workspace w = ft.translateModel(m); + + WorkspaceObjectVector idfPanels = w.getObjectsByType(IddObjectType::ZoneHVAC_CoolingPanel_RadiantConvective_Water); + ASSERT_EQ(1u, idfPanels.size()); + WorkspaceObject idfPanel(idfPanels[0]); + + // Name + EXPECT_EQ(panel.nameString(), idfPanel.getString(ZoneHVAC_CoolingPanel_RadiantConvective_WaterFields::Name).get()); + // Availability Schedule Name + EXPECT_EQ(panel.availabilitySchedule().nameString(), + idfPanel.getString(ZoneHVAC_CoolingPanel_RadiantConvective_WaterFields::AvailabilityScheduleName).get()); + // Water Inlet Node Name + EXPECT_FALSE(idfPanel.isEmpty(ZoneHVAC_CoolingPanel_RadiantConvective_WaterFields::WaterInletNodeName)); + // Water Outlet Node Name + EXPECT_FALSE(idfPanel.isEmpty(ZoneHVAC_CoolingPanel_RadiantConvective_WaterFields::WaterOutletNodeName)); + // Rated Inlet Water Temperature + EXPECT_EQ(1.0, idfPanel.getDouble(ZoneHVAC_CoolingPanel_RadiantConvective_WaterFields::RatedInletWaterTemperature).get()); + // Rated Inlet Space Temperature + EXPECT_EQ(2.0, idfPanel.getDouble(ZoneHVAC_CoolingPanel_RadiantConvective_WaterFields::RatedInletSpaceTemperature).get()); + // Rated Water Mass Flow Rate + EXPECT_EQ(3.0, idfPanel.getDouble(ZoneHVAC_CoolingPanel_RadiantConvective_WaterFields::RatedWaterMassFlowRate).get()); + // Cooling Design Capacity Method + EXPECT_EQ("FractionOfAutosizedCoolingCapacity", + idfPanel.getString(ZoneHVAC_CoolingPanel_RadiantConvective_WaterFields::CoolingDesignCapacityMethod).get()); + // Cooling Design Capacity + EXPECT_EQ(0.0, idfPanel.getDouble(ZoneHVAC_CoolingPanel_RadiantConvective_WaterFields::CoolingDesignCapacity).get()); + // Cooling Design Capacity Per Floor Area + EXPECT_EQ(0.0, idfPanel.getDouble(ZoneHVAC_CoolingPanel_RadiantConvective_WaterFields::CoolingDesignCapacityPerFloorArea).get()); + // Fraction of Autosized Cooling Design Capacity + EXPECT_EQ(4.0, idfPanel.getDouble(ZoneHVAC_CoolingPanel_RadiantConvective_WaterFields::FractionofAutosizedHeatingDesignCapacity).get()); + // Maximum Chilled Water Flow Rate + EXPECT_EQ(5.0, idfPanel.getDouble(ZoneHVAC_CoolingPanel_RadiantConvective_WaterFields::MaximumChilledWaterFlowRate).get()); + // Control Type + EXPECT_EQ("OutdoorDryBulbTemperature", idfPanel.getString(ZoneHVAC_CoolingPanel_RadiantConvective_WaterFields::ControlType).get()); + // Cooling Control Throttling Range + EXPECT_EQ(6.0, idfPanel.getDouble(ZoneHVAC_CoolingPanel_RadiantConvective_WaterFields::CoolingControlThrottlingRange).get()); + // Cooling Control Temperature Schedule Name + EXPECT_EQ(coolingControlTemperatureSchedule.nameString(), + idfPanel.getString(ZoneHVAC_CoolingPanel_RadiantConvective_WaterFields::CoolingControlTemperatureScheduleName).get()); + // Condensation Control Type + EXPECT_EQ("SimpleOff", idfPanel.getString(ZoneHVAC_CoolingPanel_RadiantConvective_WaterFields::CondensationControlType).get()); + // Condensation Control Dewpoint Offset + EXPECT_EQ(7.0, idfPanel.getDouble(ZoneHVAC_CoolingPanel_RadiantConvective_WaterFields::CondensationControlDewpointOffset).get()); + // Fraction Radiant + EXPECT_EQ(0.4, idfPanel.getDouble(ZoneHVAC_CoolingPanel_RadiantConvective_WaterFields::FractionRadiant).get()); + // Fraction of Radiant Energy Incident on People + EXPECT_EQ(0.3, idfPanel.getDouble(ZoneHVAC_CoolingPanel_RadiantConvective_WaterFields::FractionofRadiantEnergyIncidentonPeople).get()); + + double totalAreaOfWallSurfaces = 0; + double totalAreaOfCeilingSurfaces = 0; + double totalAreaOfFloorSurfaces = 0; + + for (auto const& surface : surfaces) { + if (istringEqual(surface.surfaceType(), "Floor")) { + totalAreaOfFloorSurfaces += surface.grossArea(); + } else if (istringEqual(surface.surfaceType(), "RoofCeiling")) { + totalAreaOfCeilingSurfaces += surface.grossArea(); + } else { + totalAreaOfWallSurfaces += surface.grossArea(); + } + } + + // Surface 1 Name + // Fraction of Radiant Energy to Surface 1 + EXPECT_EQ(surfaces.size(), idfPanel.numExtensibleGroups()); + for (const auto& idf_eg : idfPanel.extensibleGroups()) { + const auto& surface = surfaces[idf_eg.groupIndex()]; + + EXPECT_EQ(surface.nameString(), idf_eg.getDouble(ZoneHVAC_CoolingPanel_RadiantConvective_WaterExtensibleFields::SurfaceName).get()); + if (istringEqual(surface.surfaceType(), "Floor")) { + EXPECT_EQ(surface.grossArea() / totalAreaOfFloorSurfaces * 0.43, + idf_eg.getString(ZoneHVAC_CoolingPanel_RadiantConvective_WaterExtensibleFields::FractionofRadiantEnergytoSurface).get()); + } else if (istringEqual(surface.surfaceType(), "RoofCeiling")) { + EXPECT_EQ(surface.grossArea() / totalAreaOfCeilingSurfaces * 0.63, + idf_eg.getString(ZoneHVAC_CoolingPanel_RadiantConvective_WaterExtensibleFields::FractionofRadiantEnergytoSurface).get()); + } else { + EXPECT_EQ(surface.grossArea() / totalAreaOfWallSurfaces * 0.53, + idf_eg.getString(ZoneHVAC_CoolingPanel_RadiantConvective_WaterExtensibleFields::FractionofRadiantEnergytoSurface).get()); + } + } +} diff --git a/src/model/ZoneHVACBaseboardRadiantConvectiveElectric.cpp b/src/model/ZoneHVACBaseboardRadiantConvectiveElectric.cpp index af49907a10..eef531d7f9 100644 --- a/src/model/ZoneHVACBaseboardRadiantConvectiveElectric.cpp +++ b/src/model/ZoneHVACBaseboardRadiantConvectiveElectric.cpp @@ -188,6 +188,25 @@ namespace model { return value.get(); } + double ZoneHVACBaseboardRadiantConvectiveElectric_Impl::fractionofRadiantEnergytoFloorSurfaces() const { + boost::optional value = getDouble(OS_ZoneHVAC_Baseboard_RadiantConvective_ElectricFields::FractionofRadiantEnergytoFloorSurfaces, true); + OS_ASSERT(value); + return value.get(); + } + + double ZoneHVACBaseboardRadiantConvectiveElectric_Impl::fractionofRadiantEnergytoWallSurfaces() const { + boost::optional value = getDouble(OS_ZoneHVAC_Baseboard_RadiantConvective_ElectricFields::FractionofRadiantEnergytoWallSurfaces, true); + OS_ASSERT(value); + return value.get(); + } + + double ZoneHVACBaseboardRadiantConvectiveElectric_Impl::fractionofRadiantEnergytoCeilingSurfaces() const { + boost::optional value = + getDouble(OS_ZoneHVAC_Baseboard_RadiantConvective_ElectricFields::FractionofRadiantEnergytoCeilingSurfaces, true); + OS_ASSERT(value); + return value.get(); + } + bool ZoneHVACBaseboardRadiantConvectiveElectric_Impl::setAvailabilitySchedule(Schedule& schedule) { bool result = setSchedule(OS_ZoneHVAC_Baseboard_RadiantConvective_ElectricFields::AvailabilityScheduleName, "ZoneHVACBaseboardRadiantConvectiveElectric", "Availability", schedule); @@ -241,6 +260,25 @@ namespace model { return result; } + bool ZoneHVACBaseboardRadiantConvectiveElectric_Impl::setFractionofRadiantEnergytoFloorSurfaces(double fractionofRadiantEnergytoFloorSurfaces) { + bool result = setDouble(OS_ZoneHVAC_Baseboard_RadiantConvective_ElectricFields::FractionofRadiantEnergytoFloorSurfaces, + fractionofRadiantEnergytoFloorSurfaces); + return result; + } + + bool ZoneHVACBaseboardRadiantConvectiveElectric_Impl::setFractionofRadiantEnergytoWallSurfaces(double fractionofRadiantEnergytoWallSurfaces) { + bool result = setDouble(OS_ZoneHVAC_Baseboard_RadiantConvective_ElectricFields::FractionofRadiantEnergytoWallSurfaces, + fractionofRadiantEnergytoWallSurfaces); + return result; + } + + bool + ZoneHVACBaseboardRadiantConvectiveElectric_Impl::setFractionofRadiantEnergytoCeilingSurfaces(double fractionofRadiantEnergytoCeilingSurfaces) { + bool result = setDouble(OS_ZoneHVAC_Baseboard_RadiantConvective_ElectricFields::FractionofRadiantEnergytoCeilingSurfaces, + fractionofRadiantEnergytoCeilingSurfaces); + return result; + } + boost::optional ZoneHVACBaseboardRadiantConvectiveElectric_Impl::optionalAvailabilitySchedule() const { return getObject().getModelObjectTarget( OS_ZoneHVAC_Baseboard_RadiantConvective_ElectricFields::AvailabilityScheduleName); @@ -311,6 +349,12 @@ namespace model { OS_ASSERT(ok); ok = setFractionofRadiantEnergyIncidentonPeople(0.3); OS_ASSERT(ok); + ok = setFractionofRadiantEnergytoFloorSurfaces(0.05); // Assume that 5% of what is not on people is on the floor + OS_ASSERT(ok); + ok = setFractionofRadiantEnergytoWallSurfaces(0.55); // Assume that 55% of what is not on people is on the walls + OS_ASSERT(ok); + ok = setFractionofRadiantEnergytoCeilingSurfaces(0.40); // Assume that 40% of what is not on people is on the ceiling + OS_ASSERT(ok); } IddObjectType ZoneHVACBaseboardRadiantConvectiveElectric::iddObjectType() { @@ -358,6 +402,18 @@ namespace model { return getImpl()->fractionofRadiantEnergyIncidentonPeople(); } + double ZoneHVACBaseboardRadiantConvectiveElectric::fractionofRadiantEnergytoFloorSurfaces() const { + return getImpl()->fractionofRadiantEnergytoFloorSurfaces(); + } + + double ZoneHVACBaseboardRadiantConvectiveElectric::fractionofRadiantEnergytoWallSurfaces() const { + return getImpl()->fractionofRadiantEnergytoWallSurfaces(); + } + + double ZoneHVACBaseboardRadiantConvectiveElectric::fractionofRadiantEnergytoCeilingSurfaces() const { + return getImpl()->fractionofRadiantEnergytoCeilingSurfaces(); + } + bool ZoneHVACBaseboardRadiantConvectiveElectric::setAvailabilitySchedule(Schedule& schedule) { return getImpl()->setAvailabilitySchedule(schedule); } @@ -397,6 +453,21 @@ namespace model { fractionofRadiantEnergyIncidentonPeople); } + bool ZoneHVACBaseboardRadiantConvectiveElectric::setFractionofRadiantEnergytoFloorSurfaces(double fractionofRadiantEnergytoFloorSurfaces) { + return getImpl()->setFractionofRadiantEnergytoFloorSurfaces( + fractionofRadiantEnergytoFloorSurfaces); + } + + bool ZoneHVACBaseboardRadiantConvectiveElectric::setFractionofRadiantEnergytoWallSurfaces(double fractionofRadiantEnergytoWallSurfaces) { + return getImpl()->setFractionofRadiantEnergytoWallSurfaces( + fractionofRadiantEnergytoWallSurfaces); + } + + bool ZoneHVACBaseboardRadiantConvectiveElectric::setFractionofRadiantEnergytoCeilingSurfaces(double fractionofRadiantEnergytoCeilingSurfaces) { + return getImpl()->setFractionofRadiantEnergytoCeilingSurfaces( + fractionofRadiantEnergytoCeilingSurfaces); + } + boost::optional ZoneHVACBaseboardRadiantConvectiveElectric::thermalZone() const { return getImpl()->thermalZone(); } diff --git a/src/model/ZoneHVACBaseboardRadiantConvectiveElectric.hpp b/src/model/ZoneHVACBaseboardRadiantConvectiveElectric.hpp index 49572272a1..97423288e9 100644 --- a/src/model/ZoneHVACBaseboardRadiantConvectiveElectric.hpp +++ b/src/model/ZoneHVACBaseboardRadiantConvectiveElectric.hpp @@ -65,6 +65,12 @@ namespace model { double fractionofRadiantEnergyIncidentonPeople() const; + double fractionofRadiantEnergytoFloorSurfaces() const; + + double fractionofRadiantEnergytoWallSurfaces() const; + + double fractionofRadiantEnergytoCeilingSurfaces() const; + //@} /** @name Setters */ //@{ @@ -87,6 +93,12 @@ namespace model { bool setFractionofRadiantEnergyIncidentonPeople(double fractionofRadiantEnergyIncidentonPeople); + bool setFractionofRadiantEnergytoFloorSurfaces(double fractionofRadiantEnergytoFloorSurfaces); + + bool setFractionofRadiantEnergytoWallSurfaces(double fractionofRadiantEnergytoWallSurfaces); + + bool setFractionofRadiantEnergytoCeilingSurfaces(double fractionofRadiantEnergytoCeilingSurfaces); + //@} /** @name Other */ //@{ diff --git a/src/model/ZoneHVACBaseboardRadiantConvectiveElectric_Impl.hpp b/src/model/ZoneHVACBaseboardRadiantConvectiveElectric_Impl.hpp index 20fca6a919..77f612a5a3 100644 --- a/src/model/ZoneHVACBaseboardRadiantConvectiveElectric_Impl.hpp +++ b/src/model/ZoneHVACBaseboardRadiantConvectiveElectric_Impl.hpp @@ -81,6 +81,12 @@ namespace model { double fractionofRadiantEnergyIncidentonPeople() const; + double fractionofRadiantEnergytoFloorSurfaces() const; + + double fractionofRadiantEnergytoWallSurfaces() const; + + double fractionofRadiantEnergytoCeilingSurfaces() const; + boost::optional autosizedHeatingDesignCapacity() const; virtual void autosize() override; @@ -113,6 +119,12 @@ namespace model { bool setFractionofRadiantEnergyIncidentonPeople(double fractionofRadiantEnergyIncidentonPeople); + bool setFractionofRadiantEnergytoFloorSurfaces(double fractionofRadiantEnergytoFloorSurfaces); + + bool setFractionofRadiantEnergytoWallSurfaces(double fractionofRadiantEnergytoWallSurfaces); + + bool setFractionofRadiantEnergytoCeilingSurfaces(double fractionofRadiantEnergytoCeilingSurfaces); + //@} /** @name Other */ //@{ diff --git a/src/model/ZoneHVACBaseboardRadiantConvectiveWater.cpp b/src/model/ZoneHVACBaseboardRadiantConvectiveWater.cpp index 351b3bf132..ef4f5965ad 100644 --- a/src/model/ZoneHVACBaseboardRadiantConvectiveWater.cpp +++ b/src/model/ZoneHVACBaseboardRadiantConvectiveWater.cpp @@ -188,6 +188,24 @@ namespace model { return value.get(); } + double ZoneHVACBaseboardRadiantConvectiveWater_Impl::fractionofRadiantEnergytoFloorSurfaces() const { + boost::optional value = getDouble(OS_ZoneHVAC_Baseboard_RadiantConvective_WaterFields::FractionofRadiantEnergytoFloorSurfaces, true); + OS_ASSERT(value); + return value.get(); + } + + double ZoneHVACBaseboardRadiantConvectiveWater_Impl::fractionofRadiantEnergytoWallSurfaces() const { + boost::optional value = getDouble(OS_ZoneHVAC_Baseboard_RadiantConvective_WaterFields::FractionofRadiantEnergytoWallSurfaces, true); + OS_ASSERT(value); + return value.get(); + } + + double ZoneHVACBaseboardRadiantConvectiveWater_Impl::fractionofRadiantEnergytoCeilingSurfaces() const { + boost::optional value = getDouble(OS_ZoneHVAC_Baseboard_RadiantConvective_WaterFields::FractionofRadiantEnergytoCeilingSurfaces, true); + OS_ASSERT(value); + return value.get(); + } + HVACComponent ZoneHVACBaseboardRadiantConvectiveWater_Impl::heatingCoil() const { boost::optional value = optionalHeatingCoil(); if (!value) { @@ -213,6 +231,24 @@ namespace model { return result; } + bool ZoneHVACBaseboardRadiantConvectiveWater_Impl::setFractionofRadiantEnergytoFloorSurfaces(double fractionofRadiantEnergytoFloorSurfaces) { + bool result = setDouble(OS_ZoneHVAC_Baseboard_RadiantConvective_WaterFields::FractionofRadiantEnergytoFloorSurfaces, + fractionofRadiantEnergytoFloorSurfaces); + return result; + } + + bool ZoneHVACBaseboardRadiantConvectiveWater_Impl::setFractionofRadiantEnergytoWallSurfaces(double fractionofRadiantEnergytoWallSurfaces) { + bool result = + setDouble(OS_ZoneHVAC_Baseboard_RadiantConvective_WaterFields::FractionofRadiantEnergytoWallSurfaces, fractionofRadiantEnergytoWallSurfaces); + return result; + } + + bool ZoneHVACBaseboardRadiantConvectiveWater_Impl::setFractionofRadiantEnergytoCeilingSurfaces(double fractionofRadiantEnergytoCeilingSurfaces) { + bool result = setDouble(OS_ZoneHVAC_Baseboard_RadiantConvective_WaterFields::FractionofRadiantEnergytoCeilingSurfaces, + fractionofRadiantEnergytoCeilingSurfaces); + return result; + } + bool ZoneHVACBaseboardRadiantConvectiveWater_Impl::setHeatingCoil(const HVACComponent& radBaseboardHeatingCoil) { bool result = setPointer(OS_ZoneHVAC_Baseboard_RadiantConvective_WaterFields::HeatingCoilName, radBaseboardHeatingCoil.handle()); return result; @@ -269,6 +305,12 @@ namespace model { CoilHeatingWaterBaseboardRadiant coil(model); ok = setHeatingCoil(coil); OS_ASSERT(ok); + ok = setFractionofRadiantEnergytoFloorSurfaces(0.05); // Assume that 5% of what is not on people is on the floor + OS_ASSERT(ok); + ok = setFractionofRadiantEnergytoWallSurfaces(0.55); // Assume that 55% of what is not on people is on the walls + OS_ASSERT(ok); + ok = setFractionofRadiantEnergytoCeilingSurfaces(0.40); // Assume that 40% of what is not on people is on the ceiling + OS_ASSERT(ok); } IddObjectType ZoneHVACBaseboardRadiantConvectiveWater::iddObjectType() { @@ -287,6 +329,18 @@ namespace model { return getImpl()->fractionofRadiantEnergyIncidentonPeople(); } + double ZoneHVACBaseboardRadiantConvectiveWater::fractionofRadiantEnergytoFloorSurfaces() const { + return getImpl()->fractionofRadiantEnergytoFloorSurfaces(); + } + + double ZoneHVACBaseboardRadiantConvectiveWater::fractionofRadiantEnergytoWallSurfaces() const { + return getImpl()->fractionofRadiantEnergytoWallSurfaces(); + } + + double ZoneHVACBaseboardRadiantConvectiveWater::fractionofRadiantEnergytoCeilingSurfaces() const { + return getImpl()->fractionofRadiantEnergytoCeilingSurfaces(); + } + HVACComponent ZoneHVACBaseboardRadiantConvectiveWater::heatingCoil() const { return getImpl()->heatingCoil(); } @@ -304,6 +358,21 @@ namespace model { fractionofRadiantEnergyIncidentonPeople); } + bool ZoneHVACBaseboardRadiantConvectiveWater::setFractionofRadiantEnergytoFloorSurfaces(double fractionofRadiantEnergytoFloorSurfaces) { + return getImpl()->setFractionofRadiantEnergytoFloorSurfaces( + fractionofRadiantEnergytoFloorSurfaces); + } + + bool ZoneHVACBaseboardRadiantConvectiveWater::setFractionofRadiantEnergytoWallSurfaces(double fractionofRadiantEnergytoWallSurfaces) { + return getImpl()->setFractionofRadiantEnergytoWallSurfaces( + fractionofRadiantEnergytoWallSurfaces); + } + + bool ZoneHVACBaseboardRadiantConvectiveWater::setFractionofRadiantEnergytoCeilingSurfaces(double fractionofRadiantEnergytoCeilingSurfaces) { + return getImpl()->setFractionofRadiantEnergytoCeilingSurfaces( + fractionofRadiantEnergytoCeilingSurfaces); + } + bool ZoneHVACBaseboardRadiantConvectiveWater::setHeatingCoil(const HVACComponent& radBaseboardHeatingCoil) { return getImpl()->setHeatingCoil(radBaseboardHeatingCoil); } diff --git a/src/model/ZoneHVACBaseboardRadiantConvectiveWater.hpp b/src/model/ZoneHVACBaseboardRadiantConvectiveWater.hpp index 98e7651a6f..f6c370f063 100644 --- a/src/model/ZoneHVACBaseboardRadiantConvectiveWater.hpp +++ b/src/model/ZoneHVACBaseboardRadiantConvectiveWater.hpp @@ -51,6 +51,12 @@ namespace model { double fractionofRadiantEnergyIncidentonPeople() const; + double fractionofRadiantEnergytoFloorSurfaces() const; + + double fractionofRadiantEnergytoWallSurfaces() const; + + double fractionofRadiantEnergytoCeilingSurfaces() const; + HVACComponent heatingCoil() const; //@} @@ -63,6 +69,12 @@ namespace model { bool setFractionofRadiantEnergyIncidentonPeople(double fractionofRadiantEnergyIncidentonPeople); + bool setFractionofRadiantEnergytoFloorSurfaces(double fractionofRadiantEnergytoFloorSurfaces); + + bool setFractionofRadiantEnergytoWallSurfaces(double fractionofRadiantEnergytoWallSurfaces); + + bool setFractionofRadiantEnergytoCeilingSurfaces(double fractionofRadiantEnergytoCeilingSurfaces); + bool setHeatingCoil(const HVACComponent& heatingCoil); //@} diff --git a/src/model/ZoneHVACBaseboardRadiantConvectiveWater_Impl.hpp b/src/model/ZoneHVACBaseboardRadiantConvectiveWater_Impl.hpp index 7ba7fc0543..24c5d83bf3 100644 --- a/src/model/ZoneHVACBaseboardRadiantConvectiveWater_Impl.hpp +++ b/src/model/ZoneHVACBaseboardRadiantConvectiveWater_Impl.hpp @@ -75,6 +75,12 @@ namespace model { double fractionofRadiantEnergyIncidentonPeople() const; + double fractionofRadiantEnergytoFloorSurfaces() const; + + double fractionofRadiantEnergytoWallSurfaces() const; + + double fractionofRadiantEnergytoCeilingSurfaces() const; + HVACComponent heatingCoil() const; //@} @@ -87,6 +93,12 @@ namespace model { bool setFractionofRadiantEnergyIncidentonPeople(double fractionofRadiantEnergyIncidentonPeople); + bool setFractionofRadiantEnergytoFloorSurfaces(double fractionofRadiantEnergytoFloorSurfaces); + + bool setFractionofRadiantEnergytoWallSurfaces(double fractionofRadiantEnergytoWallSurfaces); + + bool setFractionofRadiantEnergytoCeilingSurfaces(double fractionofRadiantEnergytoCeilingSurfaces); + bool setHeatingCoil(const HVACComponent& heatingCoil); //@} diff --git a/src/model/ZoneHVACCoolingPanelRadiantConvectiveWater.cpp b/src/model/ZoneHVACCoolingPanelRadiantConvectiveWater.cpp index a9cc08411f..d80a7eda81 100644 --- a/src/model/ZoneHVACCoolingPanelRadiantConvectiveWater.cpp +++ b/src/model/ZoneHVACCoolingPanelRadiantConvectiveWater.cpp @@ -190,6 +190,25 @@ namespace model { return value.get(); } + double ZoneHVACCoolingPanelRadiantConvectiveWater_Impl::fractionofRadiantEnergytoFloorSurfaces() const { + boost::optional value = getDouble(OS_ZoneHVAC_CoolingPanel_RadiantConvective_WaterFields::FractionofRadiantEnergytoFloorSurfaces, true); + OS_ASSERT(value); + return value.get(); + } + + double ZoneHVACCoolingPanelRadiantConvectiveWater_Impl::fractionofRadiantEnergytoWallSurfaces() const { + boost::optional value = getDouble(OS_ZoneHVAC_CoolingPanel_RadiantConvective_WaterFields::FractionofRadiantEnergytoWallSurfaces, true); + OS_ASSERT(value); + return value.get(); + } + + double ZoneHVACCoolingPanelRadiantConvectiveWater_Impl::fractionofRadiantEnergytoCeilingSurfaces() const { + boost::optional value = + getDouble(OS_ZoneHVAC_CoolingPanel_RadiantConvective_WaterFields::FractionofRadiantEnergytoCeilingSurfaces, true); + OS_ASSERT(value); + return value.get(); + } + HVACComponent ZoneHVACCoolingPanelRadiantConvectiveWater_Impl::coolingCoil() const { boost::optional value = optionalCoolingCoil(); if (!value) { @@ -215,6 +234,25 @@ namespace model { return result; } + bool ZoneHVACCoolingPanelRadiantConvectiveWater_Impl::setFractionofRadiantEnergytoFloorSurfaces(double fractionofRadiantEnergytoFloorSurfaces) { + bool result = setDouble(OS_ZoneHVAC_CoolingPanel_RadiantConvective_WaterFields::FractionofRadiantEnergytoFloorSurfaces, + fractionofRadiantEnergytoFloorSurfaces); + return result; + } + + bool ZoneHVACCoolingPanelRadiantConvectiveWater_Impl::setFractionofRadiantEnergytoWallSurfaces(double fractionofRadiantEnergytoWallSurfaces) { + bool result = setDouble(OS_ZoneHVAC_CoolingPanel_RadiantConvective_WaterFields::FractionofRadiantEnergytoWallSurfaces, + fractionofRadiantEnergytoWallSurfaces); + return result; + } + + bool + ZoneHVACCoolingPanelRadiantConvectiveWater_Impl::setFractionofRadiantEnergytoCeilingSurfaces(double fractionofRadiantEnergytoCeilingSurfaces) { + bool result = setDouble(OS_ZoneHVAC_CoolingPanel_RadiantConvective_WaterFields::FractionofRadiantEnergytoCeilingSurfaces, + fractionofRadiantEnergytoCeilingSurfaces); + return result; + } + bool ZoneHVACCoolingPanelRadiantConvectiveWater_Impl::setCoolingCoil(const HVACComponent& radPanelCoolingCoil) { bool result = setPointer(OS_ZoneHVAC_CoolingPanel_RadiantConvective_WaterFields::CoolingCoilName, radPanelCoolingCoil.handle()); return result; @@ -272,6 +310,12 @@ namespace model { CoilCoolingWaterPanelRadiant coil(model); ok = setCoolingCoil(coil); OS_ASSERT(ok); + ok = setFractionofRadiantEnergytoFloorSurfaces(0.05); // Assume that 5% of what is not on people is on the floor + OS_ASSERT(ok); + ok = setFractionofRadiantEnergytoWallSurfaces(0.55); // Assume that 55% of what is not on people is on the walls + OS_ASSERT(ok); + ok = setFractionofRadiantEnergytoCeilingSurfaces(0.40); // Assume that 40% of what is not on people is on the ceiling + OS_ASSERT(ok); } IddObjectType ZoneHVACCoolingPanelRadiantConvectiveWater::iddObjectType() { @@ -290,6 +334,18 @@ namespace model { return getImpl()->fractionofRadiantEnergyIncidentonPeople(); } + double ZoneHVACCoolingPanelRadiantConvectiveWater::fractionofRadiantEnergytoFloorSurfaces() const { + return getImpl()->fractionofRadiantEnergytoFloorSurfaces(); + } + + double ZoneHVACCoolingPanelRadiantConvectiveWater::fractionofRadiantEnergytoWallSurfaces() const { + return getImpl()->fractionofRadiantEnergytoWallSurfaces(); + } + + double ZoneHVACCoolingPanelRadiantConvectiveWater::fractionofRadiantEnergytoCeilingSurfaces() const { + return getImpl()->fractionofRadiantEnergytoCeilingSurfaces(); + } + HVACComponent ZoneHVACCoolingPanelRadiantConvectiveWater::coolingCoil() const { return getImpl()->coolingCoil(); } @@ -307,6 +363,21 @@ namespace model { fractionofRadiantEnergyIncidentonPeople); } + bool ZoneHVACCoolingPanelRadiantConvectiveWater::setFractionofRadiantEnergytoFloorSurfaces(double fractionofRadiantEnergytoFloorSurfaces) { + return getImpl()->setFractionofRadiantEnergytoFloorSurfaces( + fractionofRadiantEnergytoFloorSurfaces); + } + + bool ZoneHVACCoolingPanelRadiantConvectiveWater::setFractionofRadiantEnergytoWallSurfaces(double fractionofRadiantEnergytoWallSurfaces) { + return getImpl()->setFractionofRadiantEnergytoWallSurfaces( + fractionofRadiantEnergytoWallSurfaces); + } + + bool ZoneHVACCoolingPanelRadiantConvectiveWater::setFractionofRadiantEnergytoCeilingSurfaces(double fractionofRadiantEnergytoCeilingSurfaces) { + return getImpl()->setFractionofRadiantEnergytoCeilingSurfaces( + fractionofRadiantEnergytoCeilingSurfaces); + } + bool ZoneHVACCoolingPanelRadiantConvectiveWater::setCoolingCoil(const HVACComponent& radPanelCoolingCoil) { return getImpl()->setCoolingCoil(radPanelCoolingCoil); } diff --git a/src/model/ZoneHVACCoolingPanelRadiantConvectiveWater.hpp b/src/model/ZoneHVACCoolingPanelRadiantConvectiveWater.hpp index 2d9168cc94..5efd8e65b6 100644 --- a/src/model/ZoneHVACCoolingPanelRadiantConvectiveWater.hpp +++ b/src/model/ZoneHVACCoolingPanelRadiantConvectiveWater.hpp @@ -51,6 +51,12 @@ namespace model { double fractionofRadiantEnergyIncidentonPeople() const; + double fractionofRadiantEnergytoFloorSurfaces() const; + + double fractionofRadiantEnergytoWallSurfaces() const; + + double fractionofRadiantEnergytoCeilingSurfaces() const; + HVACComponent coolingCoil() const; //@} @@ -63,6 +69,12 @@ namespace model { bool setFractionofRadiantEnergyIncidentonPeople(double fractionofRadiantEnergyIncidentonPeople); + bool setFractionofRadiantEnergytoFloorSurfaces(double fractionofRadiantEnergytoFloorSurfaces); + + bool setFractionofRadiantEnergytoWallSurfaces(double fractionofRadiantEnergytoWallSurfaces); + + bool setFractionofRadiantEnergytoCeilingSurfaces(double fractionofRadiantEnergytoCeilingSurfaces); + bool setCoolingCoil(const HVACComponent& coolingCoil); //@} diff --git a/src/model/ZoneHVACCoolingPanelRadiantConvectiveWater_Impl.hpp b/src/model/ZoneHVACCoolingPanelRadiantConvectiveWater_Impl.hpp index 9545e605a5..66cfe4dc4e 100644 --- a/src/model/ZoneHVACCoolingPanelRadiantConvectiveWater_Impl.hpp +++ b/src/model/ZoneHVACCoolingPanelRadiantConvectiveWater_Impl.hpp @@ -76,6 +76,12 @@ namespace model { double fractionofRadiantEnergyIncidentonPeople() const; + double fractionofRadiantEnergytoFloorSurfaces() const; + + double fractionofRadiantEnergytoWallSurfaces() const; + + double fractionofRadiantEnergytoCeilingSurfaces() const; + HVACComponent coolingCoil() const; //@} @@ -88,6 +94,12 @@ namespace model { bool setFractionofRadiantEnergyIncidentonPeople(double fractionofRadiantEnergyIncidentonPeople); + bool setFractionofRadiantEnergytoFloorSurfaces(double fractionofRadiantEnergytoFloorSurfaces); + + bool setFractionofRadiantEnergytoWallSurfaces(double fractionofRadiantEnergytoWallSurfaces); + + bool setFractionofRadiantEnergytoCeilingSurfaces(double fractionofRadiantEnergytoCeilingSurfaces); + bool setCoolingCoil(const HVACComponent& coolingCoil); //@} diff --git a/src/model/test/ZoneHVACBaseboardRadiantConvectiveElectric_GTest.cpp b/src/model/test/ZoneHVACBaseboardRadiantConvectiveElectric_GTest.cpp index 739e975fb1..52e7af376d 100644 --- a/src/model/test/ZoneHVACBaseboardRadiantConvectiveElectric_GTest.cpp +++ b/src/model/test/ZoneHVACBaseboardRadiantConvectiveElectric_GTest.cpp @@ -9,6 +9,11 @@ #include "../ZoneHVACBaseboardRadiantConvectiveElectric.hpp" #include "../ZoneHVACBaseboardRadiantConvectiveElectric_Impl.hpp" #include "../ThermalZone.hpp" +#include "../ThermalZone_Impl.hpp" +#include "../Schedule.hpp" +#include "../Schedule_Impl.hpp" +#include "../ScheduleConstant.hpp" +#include "../ScheduleConstant_Impl.hpp" using namespace openstudio; using namespace openstudio::model; @@ -43,3 +48,37 @@ TEST_F(ModelFixture, ZoneHVACBaseboardRadiantConvectiveElectric_AddAndRemove) { zonehvac2.remove(); ASSERT_EQ(0u, tz.equipment().size()); } + +TEST_F(ModelFixture, ZoneHVACBaseboardRadiantConvectiveElectric_SetGetFields) { + Model m; + ZoneHVACBaseboardRadiantConvectiveElectric zonehvac(m); + + Schedule schedule = zonehvac.availabilitySchedule(); + boost::optional scheduleConstant = schedule.optionalCast(); + ASSERT_TRUE(scheduleConstant); + EXPECT_EQ((*scheduleConstant).value(), 1.0); + EXPECT_EQ(0.2, zonehvac.fractionRadiant()); + EXPECT_EQ(0.3, zonehvac.fractionofRadiantEnergyIncidentonPeople()); + EXPECT_EQ(0.05, zonehvac.fractionofRadiantEnergytoFloorSurfaces()); + EXPECT_EQ(0.55, zonehvac.fractionofRadiantEnergytoWallSurfaces()); + EXPECT_EQ(0.40, zonehvac.fractionofRadiantEnergytoCeilingSurfaces()); + + ScheduleConstant sched(m); + sched.setValue(0.5); + EXPECT_TRUE(zonehvac.setAvailabilitySchedule(sched)); + EXPECT_TRUE(zonehvac.setFractionRadiant(0.75)); + EXPECT_TRUE(zonehvac.setFractionofRadiantEnergyIncidentonPeople(0.35)); + EXPECT_TRUE(zonehvac.setFractionofRadiantEnergytoFloorSurfaces(0.4)); + EXPECT_TRUE(zonehvac.setFractionofRadiantEnergytoWallSurfaces(0.5)); + EXPECT_TRUE(zonehvac.setFractionofRadiantEnergytoCeilingSurfaces(0.6)); + + Schedule schedule2 = zonehvac.availabilitySchedule(); + boost::optional scheduleConstant2 = schedule2.optionalCast(); + ASSERT_TRUE(scheduleConstant2); + EXPECT_EQ((*scheduleConstant2).value(), 0.5); + EXPECT_EQ(0.75, zonehvac.fractionRadiant()); + EXPECT_EQ(0.35, zonehvac.fractionofRadiantEnergyIncidentonPeople()); + EXPECT_EQ(0.4, zonehvac.fractionofRadiantEnergytoFloorSurfaces()); + EXPECT_EQ(0.5, zonehvac.fractionofRadiantEnergytoWallSurfaces()); + EXPECT_EQ(0.6, zonehvac.fractionofRadiantEnergytoCeilingSurfaces()); +} diff --git a/src/model/test/ZoneHVACBaseboardRadiantConvectiveWater_GTest.cpp b/src/model/test/ZoneHVACBaseboardRadiantConvectiveWater_GTest.cpp index 8cd89f532c..6c6d8ba9a8 100644 --- a/src/model/test/ZoneHVACBaseboardRadiantConvectiveWater_GTest.cpp +++ b/src/model/test/ZoneHVACBaseboardRadiantConvectiveWater_GTest.cpp @@ -9,6 +9,13 @@ #include "../ZoneHVACBaseboardRadiantConvectiveWater.hpp" #include "../ZoneHVACBaseboardRadiantConvectiveWater_Impl.hpp" #include "../ThermalZone.hpp" +#include "../ThermalZone_Impl.hpp" +#include "../Schedule.hpp" +#include "../Schedule_Impl.hpp" +#include "../ScheduleConstant.hpp" +#include "../ScheduleConstant_Impl.hpp" +#include "../CoilHeatingWaterBaseboardRadiant.hpp" +#include "../CoilHeatingWaterBaseboardRadiant_Impl.hpp" using namespace openstudio; using namespace openstudio::model; @@ -43,3 +50,46 @@ TEST_F(ModelFixture, ZoneHVACBaseboardRadiantConvectiveWater_AddAndRemove) { zonehvac2.remove(); ASSERT_EQ(0u, tz.equipment().size()); } + +TEST_F(ModelFixture, ZoneHVACBaseboardRadiantConvectiveWater_SetGetFields) { + Model m; + ZoneHVACBaseboardRadiantConvectiveWater zonehvac(m); + + Schedule schedule = zonehvac.availabilitySchedule(); + boost::optional scheduleConstant = schedule.optionalCast(); + ASSERT_TRUE(scheduleConstant); + EXPECT_EQ((*scheduleConstant).value(), 1.0); + EXPECT_EQ(0.3, zonehvac.fractionRadiant()); + EXPECT_EQ(0.3, zonehvac.fractionofRadiantEnergyIncidentonPeople()); + EXPECT_EQ(0.05, zonehvac.fractionofRadiantEnergytoFloorSurfaces()); + EXPECT_EQ(0.55, zonehvac.fractionofRadiantEnergytoWallSurfaces()); + EXPECT_EQ(0.40, zonehvac.fractionofRadiantEnergytoCeilingSurfaces()); + HVACComponent coil = zonehvac.heatingCoil(); + boost::optional coilHeating = coil.optionalCast(); + ASSERT_TRUE(coilHeating); + + ScheduleConstant sched(m); + sched.setValue(0.5); + EXPECT_TRUE(zonehvac.setAvailabilitySchedule(sched)); + EXPECT_TRUE(zonehvac.setFractionRadiant(0.75)); + EXPECT_TRUE(zonehvac.setFractionofRadiantEnergyIncidentonPeople(0.35)); + EXPECT_TRUE(zonehvac.setFractionofRadiantEnergytoFloorSurfaces(0.4)); + EXPECT_TRUE(zonehvac.setFractionofRadiantEnergytoWallSurfaces(0.5)); + EXPECT_TRUE(zonehvac.setFractionofRadiantEnergytoCeilingSurfaces(0.6)); + CoilHeatingWaterBaseboardRadiant coilHeating2(m); + EXPECT_TRUE(zonehvac.setHeatingCoil(coilHeating2)); + + Schedule schedule2 = zonehvac.availabilitySchedule(); + boost::optional scheduleConstant2 = schedule2.optionalCast(); + ASSERT_TRUE(scheduleConstant2); + EXPECT_EQ((*scheduleConstant2).value(), 0.5); + EXPECT_EQ(0.75, zonehvac.fractionRadiant()); + EXPECT_EQ(0.35, zonehvac.fractionofRadiantEnergyIncidentonPeople()); + EXPECT_EQ(0.4, zonehvac.fractionofRadiantEnergytoFloorSurfaces()); + EXPECT_EQ(0.5, zonehvac.fractionofRadiantEnergytoWallSurfaces()); + EXPECT_EQ(0.6, zonehvac.fractionofRadiantEnergytoCeilingSurfaces()); + HVACComponent coil3 = zonehvac.heatingCoil(); + boost::optional coilHeating3 = coil3.optionalCast(); + ASSERT_TRUE(coilHeating3); + EXPECT_EQ(coilHeating2.nameString(), coil3.nameString()); +} diff --git a/src/model/test/ZoneHVACCoolingPanelRadiantConvectiveWater_GTest.cpp b/src/model/test/ZoneHVACCoolingPanelRadiantConvectiveWater_GTest.cpp index ad797e369c..7d53cf1c46 100644 --- a/src/model/test/ZoneHVACCoolingPanelRadiantConvectiveWater_GTest.cpp +++ b/src/model/test/ZoneHVACCoolingPanelRadiantConvectiveWater_GTest.cpp @@ -61,6 +61,9 @@ TEST_F(ModelFixture, ZoneHVACCoolingPanelRadiantConvectiveWater_SetGetFields) { EXPECT_EQ((*scheduleConstant).value(), 1.0); EXPECT_EQ(0.65, zonehvac.fractionRadiant()); EXPECT_EQ(0.2, zonehvac.fractionofRadiantEnergyIncidentonPeople()); + EXPECT_EQ(0.05, zonehvac.fractionofRadiantEnergytoFloorSurfaces()); + EXPECT_EQ(0.55, zonehvac.fractionofRadiantEnergytoWallSurfaces()); + EXPECT_EQ(0.40, zonehvac.fractionofRadiantEnergytoCeilingSurfaces()); HVACComponent coil = zonehvac.coolingCoil(); boost::optional coilCooling = coil.optionalCast(); ASSERT_TRUE(coilCooling); @@ -70,6 +73,9 @@ TEST_F(ModelFixture, ZoneHVACCoolingPanelRadiantConvectiveWater_SetGetFields) { EXPECT_TRUE(zonehvac.setAvailabilitySchedule(sched)); EXPECT_TRUE(zonehvac.setFractionRadiant(0.75)); EXPECT_TRUE(zonehvac.setFractionofRadiantEnergyIncidentonPeople(0.3)); + EXPECT_TRUE(zonehvac.setFractionofRadiantEnergytoFloorSurfaces(0.4)); + EXPECT_TRUE(zonehvac.setFractionofRadiantEnergytoWallSurfaces(0.5)); + EXPECT_TRUE(zonehvac.setFractionofRadiantEnergytoCeilingSurfaces(0.6)); CoilCoolingWaterPanelRadiant coilCooling2(m); EXPECT_TRUE(zonehvac.setCoolingCoil(coilCooling2)); @@ -79,6 +85,9 @@ TEST_F(ModelFixture, ZoneHVACCoolingPanelRadiantConvectiveWater_SetGetFields) { EXPECT_EQ((*scheduleConstant2).value(), 0.5); EXPECT_EQ(0.75, zonehvac.fractionRadiant()); EXPECT_EQ(0.3, zonehvac.fractionofRadiantEnergyIncidentonPeople()); + EXPECT_EQ(0.4, zonehvac.fractionofRadiantEnergytoFloorSurfaces()); + EXPECT_EQ(0.5, zonehvac.fractionofRadiantEnergytoWallSurfaces()); + EXPECT_EQ(0.6, zonehvac.fractionofRadiantEnergytoCeilingSurfaces()); HVACComponent coil3 = zonehvac.coolingCoil(); boost::optional coilCooling3 = coil3.optionalCast(); ASSERT_TRUE(coilCooling3); diff --git a/src/osversion/VersionTranslator.cpp b/src/osversion/VersionTranslator.cpp index b8ca3aeb3a..0fa5b5e371 100644 --- a/src/osversion/VersionTranslator.cpp +++ b/src/osversion/VersionTranslator.cpp @@ -147,7 +147,8 @@ namespace osversion { m_updateMethods[VersionString("3.9.0")] = &VersionTranslator::update_3_8_0_to_3_9_0; m_updateMethods[VersionString("3.10.0")] = &VersionTranslator::update_3_9_0_to_3_10_0; m_updateMethods[VersionString("3.11.0")] = &VersionTranslator::update_3_10_0_to_3_11_0; - m_updateMethods[VersionString("3.11.1")] = &VersionTranslator::defaultUpdate; + m_updateMethods[VersionString("3.11.1")] = &VersionTranslator::update_3_11_0_to_3_11_1; + // m_updateMethods[VersionString("3.11.1")] = &VersionTranslator::defaultUpdate; // List of previous versions that may be updated to this one. // - To increment the translator, add an entry for the version just released (branched for @@ -10225,5 +10226,74 @@ namespace osversion { return ss.str(); } // end update_3_10_0_to_3_11_0 + + std::string VersionTranslator::update_3_11_0_to_3_11_1(const IdfFile& idf_3_11_0, const IddFileAndFactoryWrapper& idd_3_11_1) { + std::stringstream ss; + boost::optional value; + + ss << idf_3_11_0.header() << '\n' << '\n'; + IdfFile targetIdf(idd_3_11_1.iddFile()); + ss << targetIdf.versionObject().get(); + + for (const IdfObject& object : idf_3_11_0.objects()) { + auto iddname = object.iddObject().name(); + + if (iddname == "OS:ZoneHVAC:Baseboard:RadiantConvective:Electric") { + + // 1 required Field has been added from 3.11.0 to 3.11.1: + // ---------------------------------------------- + // * Fraction of Radiant Energy to Floor Surfaces * 10 + // * Fraction of Radiant Energy to Wall Surfaces * 11 + // * Fraction of Radiant Energy to Ceiling Surfaces * 12 + + auto iddObject = idd_3_11_1.getObject(iddname); + IdfObject newObject(iddObject.get()); + + for (size_t i = 0; i < object.numFields(); ++i) { + if ((value = object.getString(i))) { + newObject.setString(i, value.get()); + } + } + + newObject.setDouble(10, 0.05); + newObject.setDouble(11, 0.55); + newObject.setDouble(12, 0.40); + + ss << newObject; + m_refactored.emplace_back(std::move(object), std::move(newObject)); + + } else if ((iddname == "OS:ZoneHVAC:Baseboard:RadiantConvective:Water") || (iddname == "OS:ZoneHVAC:CoolingPanel:RadiantConvective:Water")) { + + // 1 required Field has been added from 3.11.0 to 3.11.1: + // ---------------------------------------------- + // * Fraction of Radiant Energy to Floor Surfaces * 6 + // * Fraction of Radiant Energy to Wall Surfaces * 7 + // * Fraction of Radiant Energy to Ceiling Surfaces * 8 + + auto iddObject = idd_3_11_1.getObject(iddname); + IdfObject newObject(iddObject.get()); + + for (size_t i = 0; i < object.numFields(); ++i) { + if ((value = object.getString(i))) { + newObject.setString(i, value.get()); + } + } + + newObject.setDouble(6, 0.05); + newObject.setDouble(7, 0.55); + newObject.setDouble(8, 0.40); + + ss << newObject; + m_refactored.emplace_back(std::move(object), std::move(newObject)); + + // No-op + } else { + ss << object; + } + } + + return ss.str(); + + } // end update_3_11_0_to_3_11_1 } // namespace osversion } // namespace openstudio diff --git a/src/osversion/VersionTranslator.hpp b/src/osversion/VersionTranslator.hpp index e0f61fc6d6..5de4da5f84 100644 --- a/src/osversion/VersionTranslator.hpp +++ b/src/osversion/VersionTranslator.hpp @@ -239,6 +239,7 @@ namespace osversion { std::string update_3_8_0_to_3_9_0(const IdfFile& idf_3_8_0, const IddFileAndFactoryWrapper& idd_3_9_0); std::string update_3_9_0_to_3_10_0(const IdfFile& idf_3_9_0, const IddFileAndFactoryWrapper& idd_3_10_0); std::string update_3_10_0_to_3_11_0(const IdfFile& idf_3_10_0, const IddFileAndFactoryWrapper& idd_3_11_0); + std::string update_3_11_0_to_3_11_1(const IdfFile& idf_3_11_0, const IddFileAndFactoryWrapper& idd_3_11_1); IdfObject updateUrlField_0_7_1_to_0_7_2(const IdfObject& object, unsigned index); diff --git a/src/osversion/test/3_11_1/test_vt_ZoneHVACRadiantConvective.osm b/src/osversion/test/3_11_1/test_vt_ZoneHVACRadiantConvective.osm new file mode 100644 index 0000000000..acd8b8093d --- /dev/null +++ b/src/osversion/test/3_11_1/test_vt_ZoneHVACRadiantConvective.osm @@ -0,0 +1,80 @@ + +OS:Version, + {57b1bc44-fb22-4d87-bc82-4c7b5ba17a09}, !- Handle + 3.11.0; !- Version Identifier + +OS:ZoneHVAC:Baseboard:RadiantConvective:Electric, + {1f35b6e4-2add-47e6-bf9b-fd8e8ec41e0e}, !- Handle + Zone HVAC Baseboard Radiant Convective Electric 1, !- Name + {92c6b40d-1806-4b3c-8ee4-9a2463871677}, !- Availability Schedule Name + HeatingDesignCapacity, !- Heating Design Capacity Method + autosize, !- Heating Design Capacity {W} + 0, !- Heating Design Capacity Per Floor Area {W/m2} + 1, !- Fraction of Autosized Heating Design Capacity + 1, !- Efficiency + 0.2, !- Fraction Radiant + 0.31; !- Fraction of Radiant Energy Incident on People + +OS:Schedule:Constant, + {92c6b40d-1806-4b3c-8ee4-9a2463871677}, !- Handle + Always On Discrete, !- Name + {a30df0df-4191-415b-ac55-df83b4b579b8}, !- Schedule Type Limits Name + 1; !- Value + +OS:ScheduleTypeLimits, + {a30df0df-4191-415b-ac55-df83b4b579b8}, !- Handle + OnOff, !- Name + 0, !- Lower Limit Value + 1, !- Upper Limit Value + Discrete, !- Numeric Type + Availability; !- Unit Type + +OS:ZoneHVAC:Baseboard:RadiantConvective:Water, + {dcdaefcf-c65b-413e-b684-5523948c835d}, !- Handle + Zone HVAC Baseboard Radiant Convective Water 1, !- Name + {92c6b40d-1806-4b3c-8ee4-9a2463871677}, !- Availability Schedule Name + {6797e3d2-ad39-44f1-91f2-cb2d912a2dcd}, !- Heating Coil Name + 0.3, !- Fraction Radiant + 0.32; !- Fraction of Radiant Energy Incident on People + +OS:Coil:Heating:Water:Baseboard:Radiant, + {6797e3d2-ad39-44f1-91f2-cb2d912a2dcd}, !- Handle + Coil Heating Water Baseboard Radiant 1, !- Name + , !- Inlet Node Name + , !- Outlet Node Name + 87.78, !- Rated Average Water Temperature {C} + 0.063, !- Rated Water Mass Flow Rate {kg/s} + HeatingDesignCapacity, !- Heating Design Capacity Method + autosize, !- Heating Design Capacity {W} + 0, !- Heating Design Capacity Per Floor Area {W/m2} + 1, !- Fraction of Autosized Heating Design Capacity + autosize, !- Maximum Water Flow Rate {m3/s} + 0.001; !- Convergence Tolerance + +OS:ZoneHVAC:CoolingPanel:RadiantConvective:Water, + {a64e7a3b-477e-4dc9-a78f-ca5d3e794407}, !- Handle + Zone HVAC Cooling Panel Radiant Convective Water 1, !- Name + {92c6b40d-1806-4b3c-8ee4-9a2463871677}, !- Availability Schedule Name + {fe8e6c48-2b23-4f58-86fe-032946f7d399}, !- Cooling Coil Name + 0.65, !- Fraction Radiant + 0.33; !- Fraction of Radiant Energy Incident on People + +OS:Coil:Cooling:Water:Panel:Radiant, + {fe8e6c48-2b23-4f58-86fe-032946f7d399}, !- Handle + Coil Cooling Water Panel Radiant 1, !- Name + , !- Water Inlet Node Name + , !- Water Outlet Node Name + 5, !- Rated Inlet Water Temperature {C} + 24, !- Rated Inlet Space Temperature {C} + 0.063, !- Rated Water Mass Flow Rate {kg/s} + CoolingDesignCapacity, !- Cooling Design Capacity Method + autosize, !- Cooling Design Capacity {W} + 0, !- Cooling Design Capacity Per Floor Area {W/m2} + 1, !- Fraction of Autosized Cooling Design Capacity + autosize, !- Maximum Chilled Water Flow Rate {m3/s} + MeanAirTemperature, !- Control Type + 0.5, !- Cooling Control Throttling Range {deltaC} + , !- Cooling Control Temperature Schedule Name + SimpleOff, !- Condensation Control Type + 1; !- Condensation Control Dewpoint Offset {C} + diff --git a/src/osversion/test/3_11_1/test_vt_ZoneHVACRadiantConvective.rb b/src/osversion/test/3_11_1/test_vt_ZoneHVACRadiantConvective.rb new file mode 100644 index 0000000000..58d34c31e6 --- /dev/null +++ b/src/osversion/test/3_11_1/test_vt_ZoneHVACRadiantConvective.rb @@ -0,0 +1,16 @@ +#require '/usr/local/openstudio-3.11.0/Ruby/openstudio' + +include OpenStudio::Model + +m = Model.new + +brce = ZoneHVACBaseboardRadiantConvectiveElectric.new(m) +brce.setFractionofRadiantEnergyIncidentonPeople(0.31); + +brcw = ZoneHVACBaseboardRadiantConvectiveWater.new(m) +brcw.setFractionofRadiantEnergyIncidentonPeople(0.32); + +cprcw = ZoneHVACCoolingPanelRadiantConvectiveWater.new(m) +cprcw.setFractionofRadiantEnergyIncidentonPeople(0.33); + +m.save('test_vt_ZoneHVACRadiantConvective.osm', true) diff --git a/src/osversion/test/VersionTranslator_GTest.cpp b/src/osversion/test/VersionTranslator_GTest.cpp index 49c360aad2..47458c583a 100644 --- a/src/osversion/test/VersionTranslator_GTest.cpp +++ b/src/osversion/test/VersionTranslator_GTest.cpp @@ -5036,3 +5036,40 @@ TEST_F(OSVersionFixture, update_3_10_0_to_3_11_0_OutputControlFiles) { EXPECT_EQ("Yes", ocf.getString(31).get()); // Output Tarcog EXPECT_EQ("Yes", ocf.getString(32).get()); // Output Plant Component Sizing } + +TEST_F(OSVersionFixture, update_3_11_0_to_3_11_1_ZoneHVACRadiantConvective) { + openstudio::path path = resourcesPath() / toPath("osversion/3_11_1/test_vt_ZoneHVACRadiantConvective.osm"); + osversion::VersionTranslator vt; + boost::optional model = vt.loadModel(path); + ASSERT_TRUE(model) << "Failed to load " << path; + + openstudio::path outPath = resourcesPath() / toPath("osversion/3_11_1/test_vt_ZoneHVACRadiantConvective_updated.osm"); + model->save(outPath, true); + + std::vector brces = model->getObjectsByType("OS:ZoneHVAC:Baseboard:RadiantConvective:Electric"); + ASSERT_EQ(1u, brces.size()); + const auto& brce = brces.front(); + + EXPECT_EQ(0.31, brce.getDouble(9).get()); // Fraction of Radiant Energy Incident on People + EXPECT_EQ(0.05, brce.getDouble(10).get()); // Fraction of Radiant Energy to Floor Surfaces + EXPECT_EQ(0.55, brce.getDouble(11).get()); // Fraction of Radiant Energy to Wall Surfaces + EXPECT_EQ(0.40, brce.getDouble(12).get()); // Fraction of Radiant Energy to Ceiling Surfaces + + std::vector brcws = model->getObjectsByType("OS:ZoneHVAC:Baseboard:RadiantConvective:Water"); + ASSERT_EQ(1u, brcws.size()); + const auto& brcw = brcws.front(); + + EXPECT_EQ(0.32, brcw.getDouble(5).get()); // Fraction of Radiant Energy Incident on People + EXPECT_EQ(0.05, brcw.getDouble(6).get()); // Fraction of Radiant Energy to Floor Surfaces + EXPECT_EQ(0.55, brcw.getDouble(7).get()); // Fraction of Radiant Energy to Wall Surfaces + EXPECT_EQ(0.40, brcw.getDouble(8).get()); // Fraction of Radiant Energy to Ceiling Surfaces + + std::vector cprcws = model->getObjectsByType("OS:ZoneHVAC:CoolingPanel:RadiantConvective:Water"); + ASSERT_EQ(1u, cprcws.size()); + const auto& cprcw = cprcws.front(); + + EXPECT_EQ(0.33, cprcw.getDouble(5).get()); // Fraction of Radiant Energy Incident on People + EXPECT_EQ(0.05, cprcw.getDouble(6).get()); // Fraction of Radiant Energy to Floor Surfaces + EXPECT_EQ(0.55, cprcw.getDouble(7).get()); // Fraction of Radiant Energy to Wall Surfaces + EXPECT_EQ(0.40, cprcw.getDouble(8).get()); // Fraction of Radiant Energy to Ceiling Surfaces +}