Skip to content

Commit

Permalink
Fix and improve model and ft tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
joseph-robertson committed Dec 23, 2024
1 parent 42303c1 commit 9265da3
Show file tree
Hide file tree
Showing 6 changed files with 270 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -218,16 +218,16 @@ namespace energyplus {
inletNodeName = outdoorAirInletNodeName.get();
}

if (fan_) {
if (istringEqual(fanPlacement, "DrawThrough") && fan_) {
outletNodeName = baseName + " Second Evaporative Cooler - Fan Node";
} else {
outletNodeName = outdoorAirInletNodeName.get();
outletNodeName = coolerOutletNodeName.get();
}

if (secondEvaporativeCooler_->iddObject().type() == IddObjectType::EvaporativeCooler_Direct_ResearchSpecial) {
secondEvaporativeCooler_->setString(EvaporativeCooler_Direct_ResearchSpecialFields::AirInletNodeName, inletNodeName);
secondEvaporativeCooler_->setString(EvaporativeCooler_Direct_ResearchSpecialFields::AirOutletNodeName, outletNodeName);
} else if (firstEvaporativeCooler.iddObject().type() == IddObjectType::EvaporativeCooler_Indirect_ResearchSpecial) {
} else if (secondEvaporativeCooler_->iddObject().type() == IddObjectType::EvaporativeCooler_Indirect_ResearchSpecial) {
secondEvaporativeCooler_->setString(EvaporativeCooler_Indirect_ResearchSpecialFields::PrimaryAirInletNodeName, inletNodeName);
secondEvaporativeCooler_->setString(EvaporativeCooler_Indirect_ResearchSpecialFields::PrimaryAirOutletNodeName, outletNodeName);
} else {
Expand Down
165 changes: 160 additions & 5 deletions src/energyplus/Test/ZoneHVACEvaporativeCoolerUnit_GTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@
#include <utilities/idd/IddEnums.hxx>
#include <utilities/idd/IddFactory.hxx>
#include <utilities/idd/ZoneHVAC_EvaporativeCoolerUnit_FieldEnums.hxx>
#include <utilities/idd/Fan_ComponentModel_FieldEnums.hxx>
#include <utilities/idd/EvaporativeCooler_Direct_ResearchSpecial_FieldEnums.hxx>
#include <utilities/idd/EvaporativeCooler_Indirect_ResearchSpecial_FieldEnums.hxx>

using namespace openstudio::energyplus;
using namespace openstudio::model;
Expand Down Expand Up @@ -94,10 +97,12 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_ZoneHVACEvaporativeCoolerUnit) {

EXPECT_EQ(zoneHVACEvaporativeCoolerUnit.nameString(), idfObject.getString(ZoneHVAC_EvaporativeCoolerUnitFields::Name).get());
EXPECT_EQ(availabilitySchedule.nameString(), idfObject.getString(ZoneHVAC_EvaporativeCoolerUnitFields::AvailabilityScheduleName).get());
EXPECT_EQ("", idfObject.getString(ZoneHVAC_EvaporativeCoolerUnitFields::AvailabilityManagerListName).get());
EXPECT_EQ("", idfObject.getString(ZoneHVAC_EvaporativeCoolerUnitFields::OutdoorAirInletNodeName).get());
EXPECT_EQ("", idfObject.getString(ZoneHVAC_EvaporativeCoolerUnitFields::CoolerOutletNodeName).get());
EXPECT_EQ("", idfObject.getString(ZoneHVAC_EvaporativeCoolerUnitFields::ZoneReliefAirNodeName).get());
EXPECT_TRUE(idfObject.isEmpty(ZoneHVAC_EvaporativeCoolerUnitFields::AvailabilityManagerListName));
EXPECT_EQ(zoneHVACEvaporativeCoolerUnit.airInletModelObject()->nameString(),
idfObject.getString(ZoneHVAC_EvaporativeCoolerUnitFields::OutdoorAirInletNodeName).get());
EXPECT_EQ(zoneHVACEvaporativeCoolerUnit.airOutletModelObject()->nameString(),
idfObject.getString(ZoneHVAC_EvaporativeCoolerUnitFields::CoolerOutletNodeName).get());
EXPECT_TRUE(idfObject.isEmpty(ZoneHVAC_EvaporativeCoolerUnitFields::ZoneReliefAirNodeName));
EXPECT_EQ("Fan:ComponentModel", idfObject.getString(ZoneHVAC_EvaporativeCoolerUnitFields::SupplyAirFanObjectType).get());
EXPECT_EQ(supplyAirFan.nameString(), idfObject.getString(ZoneHVAC_EvaporativeCoolerUnitFields::SupplyAirFanName).get());
EXPECT_EQ(0.9, idfObject.getDouble(ZoneHVAC_EvaporativeCoolerUnitFields::DesignSupplyAirFlowRate).get());
Expand All @@ -111,6 +116,156 @@ TEST_F(EnergyPlusFixture, ForwardTranslator_ZoneHVACEvaporativeCoolerUnit) {
EXPECT_EQ("EvaporativeCooler:Indirect:ResearchSpecial",
idfObject.getString(ZoneHVAC_EvaporativeCoolerUnitFields::SecondEvaporativeCoolerObjectType).get());
EXPECT_EQ(secondEvaporativeCooler.nameString(), idfObject.getString(ZoneHVAC_EvaporativeCoolerUnitFields::SecondEvaporativeCoolerName).get());
EXPECT_EQ("", idfObject.getString(ZoneHVAC_EvaporativeCoolerUnitFields::DesignSpecificationZoneHVACSizingObjectName).get());
EXPECT_TRUE(idfObject.isEmpty(ZoneHVAC_EvaporativeCoolerUnitFields::DesignSpecificationZoneHVACSizingObjectName));
EXPECT_EQ(95.0, idfObject.getDouble(ZoneHVAC_EvaporativeCoolerUnitFields::ShutOffRelativeHumidity).get());

auto idf_supplyAirFan = idfObject.getTarget(ZoneHVAC_EvaporativeCoolerUnitFields::SupplyAirFanName).get();
EXPECT_EQ(idf_supplyAirFan.iddObject().type(), IddObjectType::Fan_ComponentModel);

auto idf_firstEvaporativeCooler = idfObject.getTarget(ZoneHVAC_EvaporativeCoolerUnitFields::FirstEvaporativeCoolerObjectName).get();
EXPECT_EQ(idf_firstEvaporativeCooler.iddObject().type(), IddObjectType::EvaporativeCooler_Direct_ResearchSpecial);

auto idf_secondEvaporativeCooler = idfObject.getTarget(ZoneHVAC_EvaporativeCoolerUnitFields::SecondEvaporativeCoolerName).get();
EXPECT_EQ(idf_secondEvaporativeCooler.iddObject().type(), IddObjectType::EvaporativeCooler_Indirect_ResearchSpecial);

EXPECT_EQ(zoneHVACEvaporativeCoolerUnit.airInletModelObject()->nameString(),
idf_supplyAirFan.getString(Fan_ComponentModelFields::AirInletNodeName).get());
EXPECT_EQ(zoneHVACEvaporativeCoolerUnit.nameString() + " Fan - First Evaporative Cooler Node",
idf_supplyAirFan.getString(Fan_ComponentModelFields::AirOutletNodeName).get());

EXPECT_EQ(zoneHVACEvaporativeCoolerUnit.nameString() + " Fan - First Evaporative Cooler Node",
idf_firstEvaporativeCooler.getString(EvaporativeCooler_Direct_ResearchSpecialFields::AirInletNodeName).get());
EXPECT_EQ(zoneHVACEvaporativeCoolerUnit.nameString() + " First Evaporative Cooler - Second Evaporative Cooler Node",
idf_firstEvaporativeCooler.getString(EvaporativeCooler_Direct_ResearchSpecialFields::AirOutletNodeName).get());

EXPECT_EQ(zoneHVACEvaporativeCoolerUnit.nameString() + " First Evaporative Cooler - Second Evaporative Cooler Node",
idf_secondEvaporativeCooler.getString(EvaporativeCooler_Indirect_ResearchSpecialFields::PrimaryAirInletNodeName).get());
EXPECT_EQ(zoneHVACEvaporativeCoolerUnit.airOutletModelObject()->nameString(),
idf_secondEvaporativeCooler.getString(EvaporativeCooler_Indirect_ResearchSpecialFields::PrimaryAirOutletNodeName).get());
}

std::vector<std::string> getEvaporativeCoolerUnitNodes(const Workspace& workspace) {
WorkspaceObjectVector idfEvaporativeCoolerUnits(workspace.getObjectsByType(IddObjectType::ZoneHVAC_EvaporativeCoolerUnit));
if (idfEvaporativeCoolerUnits.empty()) {
return {};
}

auto& idfEvaporativeCoolerUnit = idfEvaporativeCoolerUnits[0];

return {
idfEvaporativeCoolerUnit.getString(ZoneHVAC_EvaporativeCoolerUnitFields::OutdoorAirInletNodeName).get(),
idfEvaporativeCoolerUnit.getString(ZoneHVAC_EvaporativeCoolerUnitFields::CoolerOutletNodeName).get(),
};
}

std::vector<std::string> getSupplyAirFanNodes(const Workspace& workspace) {
WorkspaceObjectVector idfFans(workspace.getObjectsByType(IddObjectType::Fan_ComponentModel));
if (idfFans.empty()) {
return {};
}

auto& idfFan = idfFans[0];

return {
idfFan.getString(Fan_ComponentModelFields::AirInletNodeName).get(),
idfFan.getString(Fan_ComponentModelFields::AirOutletNodeName).get(),
};
}

std::vector<std::string> getFirstEvaporativeCoolerNodes(const Workspace& workspace) {
WorkspaceObjectVector idfFirstEvaporativeCoolers(workspace.getObjectsByType(IddObjectType::EvaporativeCooler_Direct_ResearchSpecial));
if (idfFirstEvaporativeCoolers.empty()) {
return {};
}

auto& idfFirstEvaporativeCooler = idfFirstEvaporativeCoolers[0];

return {
idfFirstEvaporativeCooler.getString(EvaporativeCooler_Direct_ResearchSpecialFields::AirInletNodeName).get(),
idfFirstEvaporativeCooler.getString(EvaporativeCooler_Direct_ResearchSpecialFields::AirOutletNodeName).get(),
};
}

std::vector<std::string> getSecondEvaporativeCoolerNodes(const Workspace& workspace) {
WorkspaceObjectVector idfSecondEvaporativeCoolers(workspace.getObjectsByType(IddObjectType::EvaporativeCooler_Indirect_ResearchSpecial));
if (idfSecondEvaporativeCoolers.empty()) {
return {};
}

auto& idfSecondEvaporativeCooler = idfSecondEvaporativeCoolers[0];

return {
idfSecondEvaporativeCooler.getString(EvaporativeCooler_Indirect_ResearchSpecialFields::PrimaryAirInletNodeName).get(),
idfSecondEvaporativeCooler.getString(EvaporativeCooler_Indirect_ResearchSpecialFields::PrimaryAirOutletNodeName).get(),
};
}

TEST_F(EnergyPlusFixture, ForwardTranslator_ZoneHVACEvaporativeCoolerUnit_Nodes) {
for (std::string fanPlacement : {"BlowThrough", "DrawThrough"}) {

// first evaporative cooler
{
Model m;

ZoneHVACEvaporativeCoolerUnit zoneHVACEvaporativeCoolerUnit(m);
zoneHVACEvaporativeCoolerUnit.setFanPlacement(fanPlacement);

ThermalZone z(m);
zoneHVACEvaporativeCoolerUnit.addToThermalZone(z);
Space s(m);
s.setThermalZone(z);

ForwardTranslator ft;
Workspace workspace = ft.translateModel(m);

std::vector<std::string> evaporativeCoolerUnitNodes = getEvaporativeCoolerUnitNodes(workspace);
std::vector<std::string> fanNodes = getSupplyAirFanNodes(workspace);
std::vector<std::string> firstEvaporativeCoolerNodes = getFirstEvaporativeCoolerNodes(workspace);

if (fanPlacement == "BlowThrough") {
EXPECT_EQ(evaporativeCoolerUnitNodes[0], fanNodes[0]);
EXPECT_EQ(fanNodes[1], firstEvaporativeCoolerNodes[0]);
EXPECT_EQ(firstEvaporativeCoolerNodes[1], evaporativeCoolerUnitNodes[1]);
} else if (fanPlacement == "DrawThrough") {
EXPECT_EQ(evaporativeCoolerUnitNodes[0], firstEvaporativeCoolerNodes[0]);
EXPECT_EQ(firstEvaporativeCoolerNodes[1], fanNodes[0]);
EXPECT_EQ(fanNodes[1], evaporativeCoolerUnitNodes[1]);
}
}

// first evaporative cooler, second evaporative cooler
{
Model m;

ZoneHVACEvaporativeCoolerUnit zoneHVACEvaporativeCoolerUnit(m);
zoneHVACEvaporativeCoolerUnit.setFanPlacement(fanPlacement);
EvaporativeCoolerIndirectResearchSpecial secondEvaporativeCooler(m);
EXPECT_TRUE(zoneHVACEvaporativeCoolerUnit.setSecondEvaporativeCooler(secondEvaporativeCooler));

ThermalZone z(m);
zoneHVACEvaporativeCoolerUnit.addToThermalZone(z);
Space s(m);
s.setThermalZone(z);

ForwardTranslator ft;
Workspace workspace = ft.translateModel(m);

std::vector<std::string> evaporativeCoolerUnitNodes = getEvaporativeCoolerUnitNodes(workspace);
std::vector<std::string> fanNodes = getSupplyAirFanNodes(workspace);
std::vector<std::string> firstEvaporativeCoolerNodes = getFirstEvaporativeCoolerNodes(workspace);
std::vector<std::string> secondEvaporativeCoolerNodes = getSecondEvaporativeCoolerNodes(workspace);

if (fanPlacement == "BlowThrough") {
EXPECT_EQ(evaporativeCoolerUnitNodes[0], fanNodes[0]);
EXPECT_EQ(fanNodes[1], firstEvaporativeCoolerNodes[0]);
EXPECT_EQ(firstEvaporativeCoolerNodes[1], secondEvaporativeCoolerNodes[0]);
EXPECT_EQ(secondEvaporativeCoolerNodes[1], evaporativeCoolerUnitNodes[1]);
} else if (fanPlacement == "DrawThrough") {
EXPECT_EQ(evaporativeCoolerUnitNodes[0], firstEvaporativeCoolerNodes[0]);
EXPECT_EQ(firstEvaporativeCoolerNodes[1], secondEvaporativeCoolerNodes[0]);
EXPECT_EQ(secondEvaporativeCoolerNodes[1], fanNodes[0]);
EXPECT_EQ(fanNodes[1], evaporativeCoolerUnitNodes[1]);
}
}
}
}
91 changes: 85 additions & 6 deletions src/model/ZoneHVACEvaporativeCoolerUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,44 @@ namespace model {
bool keepHandle)
: ZoneHVACComponent_Impl(other, model, keepHandle) {}

ModelObject ZoneHVACEvaporativeCoolerUnit_Impl::clone(Model model) const {
auto evaporativeCoolUnitClone = ZoneHVACComponent_Impl::clone(model).cast<ZoneHVACEvaporativeCoolerUnit>();

if (OptionalHVACComponent intermediate = optionalSupplyAirFan()) {
evaporativeCoolUnitClone.setSupplyAirFan(intermediate->clone(model).cast<HVACComponent>());
}
if (OptionalHVACComponent intermediate = optionalFirstEvaporativeCooler()) {
evaporativeCoolUnitClone.setFirstEvaporativeCooler(intermediate->clone(model).cast<HVACComponent>());
}
if (OptionalHVACComponent intermediate = secondEvaporativeCooler()) {
evaporativeCoolUnitClone.setSecondEvaporativeCooler(intermediate->clone(model).cast<HVACComponent>());
}

return std::move(evaporativeCoolUnitClone);
}

std::vector<IdfObject> ZoneHVACEvaporativeCoolerUnit_Impl::remove() {
std::vector<IdfObject> result;

if (OptionalHVACComponent intermediate = optionalSupplyAirFan()) {
std::vector<IdfObject> removedSupplyAirFans = intermediate->remove();
result.insert(result.end(), removedSupplyAirFans.begin(), removedSupplyAirFans.end());
}
if (OptionalHVACComponent intermediate = optionalFirstEvaporativeCooler()) {
std::vector<IdfObject> removedFirstEvaporativeCoolers = intermediate->remove();
result.insert(result.end(), removedFirstEvaporativeCoolers.begin(), removedFirstEvaporativeCoolers.end());
}
if (OptionalHVACComponent intermediate = secondEvaporativeCooler()) {
std::vector<IdfObject> removedSecondEvaporativeCoolers = intermediate->remove();
result.insert(result.end(), removedSecondEvaporativeCoolers.begin(), removedSecondEvaporativeCoolers.end());
}

std::vector<IdfObject> removedZoneHVACEvaporativeCoolerUnit = ZoneHVACComponent_Impl::remove();
result.insert(result.end(), removedZoneHVACEvaporativeCoolerUnit.begin(), removedZoneHVACEvaporativeCoolerUnit.end());

return result;
}

const std::vector<std::string>& ZoneHVACEvaporativeCoolerUnit_Impl::outputVariableNames() const {
static std::vector<std::string> result;
if (result.empty()) {
Expand All @@ -91,6 +129,20 @@ namespace model {
return result;
}

std::vector<ModelObject> ZoneHVACEvaporativeCoolerUnit_Impl::children() const {
std::vector<ModelObject> result;
if (OptionalHVACComponent intermediate = optionalSupplyAirFan()) {
result.push_back(*intermediate);
}
if (OptionalHVACComponent intermediate = optionalFirstEvaporativeCooler()) {
result.push_back(*intermediate);
}
if (OptionalHVACComponent intermediate = secondEvaporativeCooler()) {
result.push_back(*intermediate);
}
return result;
}

unsigned ZoneHVACEvaporativeCoolerUnit_Impl::inletPort() const {
return OS_ZoneHVAC_EvaporativeCoolerUnitFields::OutdoorAirInletNodeName;
}
Expand All @@ -100,19 +152,46 @@ namespace model {
}

ComponentType ZoneHVACEvaporativeCoolerUnit_Impl::componentType() const {
return ComponentType::None;
return ComponentType::Cooling;
}

std::vector<FuelType> ZoneHVACEvaporativeCoolerUnit_Impl::coolingFuelTypes() const {
return {};
std::set<FuelType> result;
for (auto ft : firstEvaporativeCooler().coolingFuelTypes()) {
result.insert(ft);
}
if (auto secondEvaporativeCooler_ = secondEvaporativeCooler()) {
for (auto ft : secondEvaporativeCooler_->coolingFuelTypes()) {
result.insert(ft);
}
}
return {result.begin(), result.end()};
}

std::vector<FuelType> ZoneHVACEvaporativeCoolerUnit_Impl::heatingFuelTypes() const {
return {};
std::set<FuelType> result;
for (auto ft : firstEvaporativeCooler().heatingFuelTypes()) {
result.insert(ft);
}
if (auto secondEvaporativeCooler_ = secondEvaporativeCooler()) {
for (auto ft : secondEvaporativeCooler_->heatingFuelTypes()) {
result.insert(ft);
}
}
return {result.begin(), result.end()};
}

std::vector<AppGFuelType> ZoneHVACEvaporativeCoolerUnit_Impl::appGHeatingFuelTypes() const {
return {};
std::set<AppGFuelType> result;
for (auto ft : firstEvaporativeCooler().appGHeatingFuelTypes()) {
result.insert(ft);
}
if (auto secondEvaporativeCooler_ = secondEvaporativeCooler()) {
for (auto ft : secondEvaporativeCooler_->appGHeatingFuelTypes()) {
result.insert(ft);
}
}
return {result.begin(), result.end()};
}

Schedule ZoneHVACEvaporativeCoolerUnit_Impl::availabilitySchedule() const {
Expand Down Expand Up @@ -286,7 +365,7 @@ namespace model {
ok = setAvailabilitySchedule(alwaysOn);
OS_ASSERT(ok);

FanComponentModel supplyAirFan(model); // StripMallZoneEvapCooler.idf
FanComponentModel supplyAirFan(model);
ok = setSupplyAirFan(supplyAirFan);
OS_ASSERT(ok);

Expand All @@ -301,7 +380,7 @@ namespace model {
OS_ASSERT(ok);

EvaporativeCoolerDirectResearchSpecial firstEvaporativeCooler(model, alwaysOn);
ok = setFirstEvaporativeCooler(firstEvaporativeCooler); // StripMallZoneEvapCooler.idf
ok = setFirstEvaporativeCooler(firstEvaporativeCooler);
OS_ASSERT(ok);

ok = setShutOffRelativeHumidity(100.0);
Expand Down
6 changes: 6 additions & 0 deletions src/model/ZoneHVACEvaporativeCoolerUnit_Impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,18 @@ namespace model {
/** @name Virtual Methods */
//@{

virtual ModelObject clone(Model model) const override;

virtual std::vector<IdfObject> remove() override;

virtual const std::vector<std::string>& outputVariableNames() const override;

virtual IddObjectType iddObjectType() const override;

virtual std::vector<ScheduleTypeKey> getScheduleTypeKeys(const Schedule& schedule) const override;

virtual std::vector<ModelObject> children() const override;

virtual unsigned inletPort() const override;

virtual unsigned outletPort() const override;
Expand Down
6 changes: 3 additions & 3 deletions src/model/test/ZoneHVACEvaporativeCoolerUnit_GTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ TEST_F(ModelFixture, ZoneHVACEvaporativeCoolerUnit_HeatCoolFuelTypes) {

ZoneHVACEvaporativeCoolerUnit zoneHVACEvaporativeCoolerUnit(m);

EXPECT_EQ(ComponentType(ComponentType::Both), zoneHVACEvaporativeCoolerUnit.componentType());
EXPECT_EQ(ComponentType(ComponentType::Cooling), zoneHVACEvaporativeCoolerUnit.componentType());
testFuelTypeEquality({FuelType::Electricity}, zoneHVACEvaporativeCoolerUnit.coolingFuelTypes());
testFuelTypeEquality({FuelType::Electricity, FuelType::Propane}, zoneHVACEvaporativeCoolerUnit.heatingFuelTypes());
testAppGFuelTypeEquality({AppGFuelType::Fuel, AppGFuelType::HeatPump}, zoneHVACEvaporativeCoolerUnit.appGHeatingFuelTypes());
testFuelTypeEquality({}, zoneHVACEvaporativeCoolerUnit.heatingFuelTypes());
testAppGFuelTypeEquality({}, zoneHVACEvaporativeCoolerUnit.appGHeatingFuelTypes());
}
Loading

0 comments on commit 9265da3

Please sign in to comment.