-
Notifications
You must be signed in to change notification settings - Fork 197
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wrap ZoneHVAC:EvaporativeCoolerUnit #5326
base: develop
Are you sure you want to change the base?
Conversation
resources/model/OpenStudio.idd
Outdated
A5, \field Outdoor Air Inlet Node Name | ||
\required-field | ||
\type object-list | ||
\object-list ConnectionNames | ||
\note this is an outdoor air node |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you may want to not add it?
resources/model/OpenStudio.idd
Outdated
A11, \field First Evaporative Cooler Object Name | ||
\required-field | ||
\type object-list | ||
\object-list EvapCoolerNames | ||
A12, \field Second Evaporative Cooler Name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this is just E+. still bothers me that the second doesn't have "Object" in it.
In any case, beware here because GenerateClass.rb will name the getters/setters differently and we don't want that.
I'd remove both "Object Name" from it, so that the getters are firstEvaporativeCooler
and secondEvaporativeCooler
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pretty minor comments (mostly: tests), this is looking very good otherwise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be good to add tests for:
- Nodes/Connections:
- addToThermalZone (are the inlet/outlet nodes set correctly)
- addToNode.
- Not familiar with this object, but at least it should be rejected on a PlantLoop, Not sure about AirLoopHVAC (
ZoneHVACComponent
will allow a connection with anAirTerminalSingleDuctInletSideMixer
). Bottom line: are the addToThermalZone & addToNode from ZoneHVACComponent doing the right thing for this object?
- clone: same model, and another model. And remove.
OpenStudio/src/model/ZoneHVACComponent.cpp
Lines 320 to 336 in 0314c3e
bool ZoneHVACComponent_Impl::addToNode(Node& node) { | |
bool result = false; | |
boost::optional<ThermalZone> thermalZone; | |
boost::optional<AirTerminalSingleDuctInletSideMixer> terminal; | |
if (boost::optional<ModelObject> outlet = node.outletModelObject()) { | |
if (boost::optional<PortList> pl = outlet->optionalCast<PortList>()) { | |
thermalZone = pl->thermalZone(); | |
} | |
} | |
if (boost::optional<ModelObject> inlet = node.inletModelObject()) { | |
terminal = inlet->optionalCast<AirTerminalSingleDuctInletSideMixer>(); | |
} | |
if (thermalZone && terminal) { |
return std::move(evaporativeCoolUnitClone); | ||
} | ||
|
||
std::vector<IdfObject> ZoneHVACEvaporativeCoolerUnit_Impl::remove() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could consider using #include "../utilities/core/ContainersMove.hpp"
, eg
OpenStudio/src/model/Building.cpp
Line 122 in 0314c3e
openstudio::detail::concat_helper(result, ParentObject_Impl::remove()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, given the way you wrote the children()
method, I'm not sure explicitly cloning the children is necessary, but I could be wrong. In the end, I only care if the (future) test shows everything works as expected.
src/osversion/VersionTranslator.cpp
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is there a (clang-format) diff here?
// Outdoor Air Inlet Node Name: Required Node | ||
if (boost::optional<Node> node = modelObject.inletNode()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do/should we catch the case where it's somehow not set?
src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACEvaporativeCoolerUnit.cpp
Outdated
Show resolved
Hide resolved
src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACEvaporativeCoolerUnit.cpp
Outdated
Show resolved
Hide resolved
src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACEvaporativeCoolerUnit.cpp
Outdated
Show resolved
Hide resolved
src/energyplus/ForwardTranslator/ForwardTranslateZoneHVACEvaporativeCoolerUnit.cpp
Outdated
Show resolved
Hide resolved
|
EXPECT_FALSE(zonehvac.remove().empty()); | ||
EXPECT_EQ(size - 1, m.modelObjects().size()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not really sure what remove
is actually supposed to remove. Looks like, without an override, it currently removes more than just the ZoneHVACEvaporativeCoolerUnit
...?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove is supposed to remove the children - that aren't resource objects - and their recursive children as well as the ZoneHVACEvaporativeCoolerUnit.
ZoneHVACEvaporativeCoolerUnit is a ZoneHVACComponent > HVACComponent > ParentObject
Eventually this is what's called.
OpenStudio/src/model/ParentObject.cpp
Lines 44 to 72 in 0314c3e
/// remove self and all children objects recursively | |
std::vector<IdfObject> ParentObject_Impl::remove() { | |
std::vector<IdfObject> result; | |
// DLM: the following code does not work because subTree includes this object | |
// and we don't want to call remove on the same object recursively | |
// | |
//ModelObjectVector subTree = getRecursiveChildren(getObject<ParentObject>()); | |
//for (ModelObject& object : subTree) { | |
// std::vector<IdfObject> removed = object.remove(); | |
// result.insert(result.end(), removed.begin(), removed.end()); | |
//} | |
// subTree includes this object, make sure to include costs as well | |
// drop the ResourceObject instances, if they are used by other objects | |
// This is probably the unique situation where you want to get children minus ResourceObjects | |
auto subTree = getRecursiveChildren(getObject<ParentObject>(), true, false); | |
result.reserve(subTree.size()); | |
for (const ModelObject& object : subTree) { | |
result.emplace_back(object.idfObject()); | |
} | |
bool ok = model().removeObjects(getHandles<ModelObject>(subTree)); | |
if (!ok) { | |
result.clear(); | |
} | |
return result; | |
} |
i'm building your PR locally, will check out the tests in a bit
|
||
Schedule availabilitySchedule() const; | ||
|
||
HVACComponent supplyAirFan() const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All fans need an addition to their containingZoneHVACComponent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is used in particular to check if the HVACComponent::isRemovable when remove() is called.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
|
||
double coolingLoadControlThresholdHeatTransferRate() const; | ||
|
||
HVACComponent firstEvaporativeCooler() const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SAme comment
There are five types of evaporative cooler component models to choose from: EvaporativeCooler:Direct:CelDekPad, EvaporativeCooler:Direct:ResearchSpecial, EvaporativeCooler:Indirect:CelDekPad, EvaporativeCooler:Indirect:WetCoil, or EvaporativeCooler:Indirect:ResearchSpecial.
For us that's EvaporativeCoolerDirectResearchSpecial
and EvaporativeCoolerIndirectResearchSpecial
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
… models `containingZoneHVACComponent` cf #5326 (comment)
@joseph-robertson I made adjustments: https://github.com/NREL/OpenStudio/pull/5326/files/4cb656d678a376bb72010aacce41d44eefd03c47..bbbda1d885418e99ff57e9094f8803acda1ceab2 You'll need to add an OpenStudio-resources test for this object and add it to the top post's checklist please |
… models `containingZoneHVACComponent` cf #5326 (comment)
bbbda1d
to
292a5d4
Compare
resources/model/OpenStudio.idd
Outdated
\object-list SystemAvailabilityManagerLists | ||
A5, \field Outdoor Air Inlet Node Name | ||
\required-field | ||
\type object-list | ||
\object-list ConnectionNames | ||
\note this is an outdoor air node | ||
A6, \field Cooler Outlet Node Name | ||
\required-field | ||
\type object-list | ||
\object-list ConnectionNames | ||
\note this is a zone inlet node | ||
A7, \field Zone Relief Air Node Name | ||
\type object-list | ||
\object-list ConnectionNames | ||
\note this is a zone exhaust node, optional if flow is being balanced elsewhere |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I think the node connections are wrong at model namespace.
You've set inletPort to be "Outdoor Air Inlet Node Name", but that should be an OA node. And I don't think it should be in the IDD, or at least it should just be a std::string (alpha) one.
inletPort should be Zone Relief Air Node Name, so that the addToThermalZone works
Zone Relief Air Node Name : This optional alpha input field defines the name of an HVAC system node which can extract air from the zone to balance the air supplied to the zone by the cooler outlet node. This node name would match the name of a zone exhaust air node.
. But we should also have a Boolean field like "Flow Is Balanced" to determine whether we write it to IDF or not (or maybe we just always assume it is balanced here, not elsewhere)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Proposed a change in 373c394
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That comment stands though:
But we should also have a Boolean field like "Flow Is Balanced" to determine whether we write it to IDF or not (or maybe we just always assume it is balanced here, not elsewhere)
… models `containingZoneHVACComponent` cf #5326 (comment)
373c394
to
d805651
Compare
boost::optional<double> ZoneHVACEvaporativeCoolerUnit_Impl::autosizedDesignSupplyAirFlowRate() { | ||
return getAutosizedValue("TODO_CHECK_SQL Design Supply Air Flow Rate", "m3/s"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO. Found after correctly adding the object to autosize_hvac.rb in OS-res PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
HVACComponent firstEvaporativeCooler = modelObject.firstEvaporativeCooler(); | ||
boost::optional<IdfObject> firstEvaporativeCooler_ = translateAndMapModelObject(firstEvaporativeCooler); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The naming of these variables is terribly confusing. More on this in a minute.
outletNodeName = baseName + " First Evaporative Cooler - Fan Node"; | ||
} | ||
|
||
if (firstEvaporativeCooler_->iddObject().type() == IddObjectType::EvaporativeCooler_Direct_ResearchSpecial) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checking the type of the IdfObject...
firstEvaporativeCooler_->setString(EvaporativeCooler_Direct_ResearchSpecialFields::AirInletNodeName, inletNodeName); | ||
firstEvaporativeCooler_->setString(EvaporativeCooler_Direct_ResearchSpecialFields::AirOutletNodeName, outletNodeName); | ||
firstEvaporativeCooler_->setString(EvaporativeCooler_Direct_ResearchSpecialFields::SensorNodeName, outletNodeName); | ||
} else if (firstEvaporativeCooler.iddObject().type() == IddObjectType::EvaporativeCooler_Indirect_ResearchSpecial) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UH OH. Checking the type of the Modelobject!!! Which is "OS:xxxx" and WILL NOT MATCH.
I revamped the OS-resources test to flip the order of the Indirect and Direct evap cooler so it's similar to https://github.com/NREL/EnergyPlus/blob/31e3c33467c5873371bf48b12a7318215971c315/testfiles/StripMallZoneEvapCoolerAutosized.idf#L4767-L4784
And I was getting empty nodes, and I couldn't figure out why. I just noticed this only after completely rewrittign the FT routine...
boost::optional<HVACComponent> _secondEvaporativeCooler = modelObject.secondEvaporativeCooler(); | ||
boost::optional<IdfObject> secondEvaporativeCooler_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that's my favourite :) leading versus trailing "_"
…e OS:XXX object This is now impossible to do because I've scoped the variable.
…me" being always filled out
* [#5326](https://github.com/NREL/OpenStudio/pull/5326) - Wrap ZoneHVAC:EvaporativeCoolerUnit | ||
* The object was wrapped in the SDK. | ||
* Note: in EnergyPlus 24.2.0, the `Zone Relief Air Node Name` is an optional field. The OpenStudio SDK always fills with the connected zone's Exhaust Air Node, meaning the airflow is always being balanced by EnergyPlus: the object will extract air from the zone to balance the air supplied to the zone by the cooler outlet node. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a note in the TDB release notes
CI Results for f8c27b8:
|
Pull request overview
Pull Request Author
src/model/test
)src/energyplus/Test
)src/osversion/VersionTranslator.cpp
)Labels:
IDDChange
APIChange
Pull Request - Ready for CI
so that CI builds your PRReview Checklist
This will not be exhaustively relevant to every PR.