Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 53 additions & 8 deletions resources/model/OpenStudio.idd
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions src/energyplus/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/***********************************************************************************************************************
* OpenStudio(R), Copyright (c) Alliance for Energy Innovation, LLC.
* See also https://openstudio.net/license
***********************************************************************************************************************/

#include <gtest/gtest.h>
#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 <utilities/idd/ZoneHVAC_Baseboard_RadiantConvective_Electric_FieldEnums.hxx>
#include <utilities/idd/IddEnums.hxx>

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<Space> 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());
}
}
}
Loading