Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
24 changes: 12 additions & 12 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -199,13 +199,13 @@ set(ENERGYPLUS_VERSION_MINOR 1)
set(ENERGYPLUS_VERSION_PATCH 0)
set(ENERGYPLUS_VERSION "${ENERGYPLUS_VERSION_MAJOR}.${ENERGYPLUS_VERSION_MINOR}.${ENERGYPLUS_VERSION_PATCH}")
# Build SHA is not required to have a value, but if it does OpenStudio will require this build.
set(ENERGYPLUS_BUILD_SHA "68a4a7c774")
set(ENERGYPLUS_BUILD_SHA "1c11a3d85f")

# ENERGYPLUS_RELEASE_NAME is used to locate the E+ download
# from the github releases
set(ENERGYPLUS_RELEASE_NAME "v25.1.0")
set(ENERGYPLUS_RELEASE_NAME "v25.1.0-WithDSOASpaceListFixes")

set(ENERGYPLUS_REPO "NREL")
set(ENERGYPLUS_REPO "jmarrec")
Comment on lines +206 to +208
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


# Radiance
set(RADIANCE_VERSION "5.0.a.12")
Expand Down Expand Up @@ -645,27 +645,27 @@ endif()
if(UNIX)
if(APPLE)
if (ARCH MATCHES "arm64")
set(ENERGYPLUS_EXPECTED_HASH e5a071a01c130aff04515641b502b1ed)
set(ENERGYPLUS_EXPECTED_HASH 7301caad82ed104f23704e6123345989)
set(ENERGYPLUS_PLATFORM "Darwin-macOS13-arm64")
else()
set(ENERGYPLUS_EXPECTED_HASH 21c6e2c536737ef837c2f58c241133cc)
set(ENERGYPLUS_EXPECTED_HASH 8746aaad0e901f640b644ffc96d4cde9)
set(ENERGYPLUS_PLATFORM "Darwin-macOS12.1-x86_64")
endif()
elseif(LSB_RELEASE_ID_SHORT MATCHES "CentOS")
set(ENERGYPLUS_EXPECTED_HASH 53aef5bb832ad7f1564ea568a60b4d12)
set(ENERGYPLUS_EXPECTED_HASH TODO_TBD_TODO)
Comment thread
jmarrec marked this conversation as resolved.
set(ENERGYPLUS_PLATFORM "Linux-CentOS7.9.2009-x86_64")
else()
if(LSB_RELEASE_VERSION_SHORT MATCHES "24.04")
if (ARCH MATCHES "arm64")
set(ENERGYPLUS_EXPECTED_HASH 4862acc3510e3bc4c9a176160f4a4c16)
set(ENERGYPLUS_EXPECTED_HASH 143d5972ba83ee676a8a789104242e19)
else()
set(ENERGYPLUS_EXPECTED_HASH 27939b216b986527c62270055bd96c7d)
set(ENERGYPLUS_EXPECTED_HASH e0733483ab27dd6887ac596c047ff4ac)
endif()
elseif(LSB_RELEASE_VERSION_SHORT MATCHES "22.04")
if (ARCH MATCHES "arm64")
set(ENERGYPLUS_EXPECTED_HASH ffef7fb46ab03eb514c105052d7a9537)
set(ENERGYPLUS_EXPECTED_HASH 66e36cf50076c87feeb12fee6bede7f5)
else()
set(ENERGYPLUS_EXPECTED_HASH a96af44c88792877cdf32e0cb90bcc42)
set(ENERGYPLUS_EXPECTED_HASH 29365cf56e4d65bac3c64a4568acecc8)
endif()
else() # e.g., 18.04, 20.04
message(FATAL_ERROR "EnergyPlus no longer provides packages for Ubuntu < 22.04")
Expand Down Expand Up @@ -702,11 +702,11 @@ elseif(WIN32)
if(CMAKE_SIZEOF_VOID_P EQUAL 8) # 64 bit
set(ENERGYPLUS_PATH "EnergyPlus-${ENERGYPLUS_VERSION}-${ENERGYPLUS_BUILD_SHA}-Windows-x86_64")
set(ENERGYPLUS_ARCH 64)
set(ENERGYPLUS_EXPECTED_HASH fbf1ec77822c33dd3c991fa1fb183ee8)
set(ENERGYPLUS_EXPECTED_HASH d4870d7e79c233c4a938df056f64ccce)
else()
set(ENERGYPLUS_PATH "EnergyPlus-${ENERGYPLUS_VERSION}-${ENERGYPLUS_BUILD_SHA}-Windows-i386")
set(ENERGYPLUS_ARCH 32)
set(ENERGYPLUS_EXPECTED_HASH e1057c847387a1e76645fc02e2625d6d)
set(ENERGYPLUS_EXPECTED_HASH TODO_TBD_TODO)
endif()
if(EXISTS "${PROJECT_BINARY_DIR}/${ENERGYPLUS_PATH}.zip")
file(MD5 "${PROJECT_BINARY_DIR}/${ENERGYPLUS_PATH}.zip" ENERGYPLUS_HASH)
Expand Down
7 changes: 4 additions & 3 deletions src/energyplus/ForwardTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1502,9 +1502,8 @@ namespace energyplus {
return retVal;
}
case openstudio::IddObjectType::OS_DesignSpecification_OutdoorAir: {
auto designSpecificationOutdoorAir = modelObject.cast<DesignSpecificationOutdoorAir>();
retVal = translateDesignSpecificationOutdoorAir(designSpecificationOutdoorAir);
break;
LOG_AND_THROW("Shouldn't get there");
return retVal;
Comment on lines 1504 to +1506
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I put that here too just to make sure

}
case openstudio::IddObjectType::OS_DesignSpecification_ZoneAirDistribution: {
// DLM: appears to be translated in SizingZone
Expand Down Expand Up @@ -4034,6 +4033,8 @@ namespace energyplus {

m_map.clear();

m_zoneDSOAsMap.clear();
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And I clear the new map when we start FTing again, of course


m_anyNumberScheduleTypeLimits.reset();

m_interiorPartitionSurfaceConstruction.reset();
Expand Down
21 changes: 19 additions & 2 deletions src/energyplus/ForwardTranslator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,11 @@ namespace energyplus {

namespace detail {
struct ForwardTranslatorInitializer;
};

// TODO: I have to put this back because of AirTerminalDualDuctVAV which should be using Control for Outdoor Air
// I'm setting it up as a free function in detail:: though, so you know you shouldn't call it!
boost::optional<IdfObject> translateDesignSpecificationOutdoorAir(model::DesignSpecificationOutdoorAir& modelObject);
Comment on lines +512 to +514
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An unfortunate thing, I was aiming to completely hide it from the API, but I can't. Fair enough...

}; // namespace detail

#define ENERGYPLUS_VERSION "25.1"

Expand Down Expand Up @@ -938,7 +942,14 @@ namespace energyplus {

boost::optional<IdfObject> translateDesignDay(model::DesignDay& modelObject);

boost::optional<IdfObject> translateDesignSpecificationOutdoorAir(model::DesignSpecificationOutdoorAir& modelObject);
// Construct (or fetch if already created) a DesignSpecificationOutdoorAir (DSOA) or DSOA:SpaceList
// * if there are no spaces with a DSOA assigned: return empty
// * otherwise:
// * otherwise:
// * if we translated to E+ with spaces:
// * If a single one: DSOA, otherwise create a DSOA:SpaceList
// * if we do not use E+ spaces: create DSOA
boost::optional<IdfObject> getOrCreateThermalZoneDSOA(const model::ThermalZone& z);
Comment on lines +945 to +952
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, now that we've got helpers in places, this is main function I'll be using going forward.

(Similar to getSpaceLoadParent)


boost::optional<IdfObject> translateDistrictCooling(model::DistrictCooling& modelObject);

Expand Down Expand Up @@ -1507,6 +1518,9 @@ namespace energyplus {
boost::optional<IdfObject> translateThermalZone(model::ThermalZone& modelObject);
void translateThermalZoneSpacesWhenCombinedSpaces(model::ThermalZone& modelObject, IdfObject& idfObject);
void translateThermalZoneSpacesToEnergyPlusSpaces(model::ThermalZone& modelObject, IdfObject& idfObject);
// Helper for the DesignSpecification:ZoneAirDistribution, returns empty when the DSZAD is not needed,
// which is when fields on Sizing:Zone related to it are all defaulted (Implemeted in ForwardTranslateSizingZone)
boost::optional<std::string> zoneDSZADName(const model::ThermalZone& zone);
Comment on lines +1521 to +1523
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New helper.


boost::optional<IdfObject> translateThermostatSetpointDualSetpoint(model::ThermostatSetpointDualSetpoint& tsds);

Expand Down Expand Up @@ -1698,6 +1712,9 @@ namespace energyplus {

ModelObjectMap m_map;

using ZoneToMaybeDSOA = std::map<const openstudio::Handle, boost::optional<IdfObject>>;
ZoneToMaybeDSOA m_zoneDSOAsMap;

std::vector<IdfObject> m_idfObjects;

boost::optional<IdfObject> m_anyNumberScheduleTypeLimits;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@
#include "../../model/Node_Impl.hpp"
#include "../../model/DesignSpecificationOutdoorAir.hpp"
#include "../../model/DesignSpecificationOutdoorAir_Impl.hpp"

#include "../../utilities/idd/IddEnums.hpp"
#include "../../utilities/plot/ProgressBar.hpp"

#include <utilities/idd/AirTerminal_DualDuct_VAV_FieldEnums.hxx>
#include <utilities/idd/ZoneHVAC_AirDistributionUnit_FieldEnums.hxx>
#include "../../utilities/idd/IddEnums.hpp"
#include <utilities/idd/IddEnums.hxx>
#include <utilities/idd/IddFactory.hxx>

Expand Down Expand Up @@ -71,8 +74,29 @@ namespace energyplus {
idfObject.setDouble(AirTerminal_DualDuct_VAVFields::ZoneMinimumAirFlowFraction, value);
}

// TODO: replace with "Control for Outdoor Air!"
if (auto designOA = modelObject.designSpecificationOutdoorAirObject()) {
if (auto idf = translateAndMapModelObject(designOA.get())) {

auto translateAndMapDSOA = [this](DesignSpecificationOutdoorAir& dsoa) -> boost::optional<IdfObject> {
auto objInMapIt = m_map.find(dsoa.handle());
if (objInMapIt != m_map.end()) {
return objInMapIt->second;
}

auto idf_dsoa_ = detail::translateDesignSpecificationOutdoorAir(dsoa);

if (idf_dsoa_) {
m_idfObjects.push_back(*idf_dsoa_);
m_map.emplace(dsoa.handle(), *idf_dsoa_);
}

if (m_progressBar) {
m_progressBar->setValue((int)m_map.size());
}
return idf_dsoa_;
};

if (auto idf = translateAndMapDSOA(designOA.get())) {
idfObject.setString(AirTerminal_DualDuct_VAVFields::DesignSpecificationOutdoorAirObjectName, idf->name().get());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,29 +76,26 @@ namespace energyplus {

// ControlForOutdoorAir: if yes, get the zone's space's DSOA
{
bool dsoa_found = false;
if (modelObject.controlForOutdoorAir()) {
bool dsoa_found = false;
if (auto airLoopHVAC = modelObject.airLoopHVAC()) {
auto zones = airLoopHVAC->demandComponents(modelObject, airLoopHVAC->demandOutletNode(), model::ThermalZone::iddObjectType());
if (!zones.empty()) {
auto zone = zones.front();
auto spaces = zone.cast<model::ThermalZone>().spaces();
if (!spaces.empty()) {
if (auto designSpecificationOutdoorAir = spaces.front().designSpecificationOutdoorAir()) {
idfObject.setString(AirTerminal_DualDuct_VAV_OutdoorAirFields::DesignSpecificationOutdoorAirObjectName,
designSpecificationOutdoorAir->name().get());
dsoa_found = true;
}
if (auto dsoaOrList_ = getOrCreateThermalZoneDSOA(zone.cast<ThermalZone>())) {
idfObject.setString(AirTerminal_DualDuct_VAV_OutdoorAirFields::DesignSpecificationOutdoorAirObjectName, dsoaOrList_->nameString());
dsoa_found = true;
}
}
}
}
if (!dsoa_found) {
LOG(Error, "Cannot set the Required 'Design Specification Outdoor Air' (DSOA) object for "
<< modelObject.briefDescription()
<< ". You should set controlForOutdoorAir to 'true' and ensure the zone's Space/SpaceType has a DSOA attached.");
if (!dsoa_found) {
LOG(Error, "Cannot set the Required 'Design Specification Outdoor Air' (DSOA) object for "
<< modelObject.briefDescription()
<< ". You should set controlForOutdoorAir to 'true' and ensure the zone's Space/SpaceType has a DSOA attached.");
}
}
}

// Populate fields for AirDistributionUnit
if (boost::optional<ModelObject> outletNode = modelObject.outletModelObject()) {
_airDistributionUnit.setString(ZoneHVAC_AirDistributionUnitFields::AirDistributionUnitOutletNodeName, outletNode->name().get());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,9 @@ namespace energyplus {
auto zones = airLoopHVAC->demandComponents(modelObject, airLoopHVAC->demandOutletNode(), model::ThermalZone::iddObjectType());
if (!zones.empty()) {
auto zone = zones.front();
auto spaces = zone.cast<model::ThermalZone>().spaces();
if (!spaces.empty()) {
if (auto designSpecificationOutdoorAir = spaces.front().designSpecificationOutdoorAir()) {
dsoa_found = true;
idfObject.setString(AirTerminal_SingleDuct_MixerFields::DesignSpecificationOutdoorAirObjectName,
designSpecificationOutdoorAir->name().get());
}
if (auto dsoaOrList_ = getOrCreateThermalZoneDSOA(zone.cast<ThermalZone>())) {
dsoa_found = true;
idfObject.setString(AirTerminal_SingleDuct_MixerFields::DesignSpecificationOutdoorAirObjectName, dsoaOrList_->nameString());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,8 @@ namespace energyplus {
auto zones = airLoopHVAC->demandComponents(modelObject, airLoopHVAC->demandOutletNode(), model::ThermalZone::iddObjectType());
if (!zones.empty()) {
auto zone = zones.front();
auto spaces = zone.cast<model::ThermalZone>().spaces();
if (!spaces.empty()) {
if (auto designSpecificationOutdoorAir = spaces.front().designSpecificationOutdoorAir()) {
idfObject.setString(AirTerminal_SingleDuct_VAV_NoReheatFields::DesignSpecificationOutdoorAirObjectName,
designSpecificationOutdoorAir->name().get());
}
if (auto dsoaOrList_ = getOrCreateThermalZoneDSOA(zone.cast<ThermalZone>())) {
idfObject.setString(AirTerminal_SingleDuct_VAV_NoReheatFields::DesignSpecificationOutdoorAirObjectName, dsoaOrList_->nameString());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,12 +207,8 @@ namespace energyplus {
auto zones = airLoopHVAC->demandComponents(modelObject, airLoopHVAC->demandOutletNode(), model::ThermalZone::iddObjectType());
if (!zones.empty()) {
auto zone = zones.front();
auto spaces = zone.cast<model::ThermalZone>().spaces();
if (!spaces.empty()) {
if (auto designSpecificationOutdoorAir = spaces.front().designSpecificationOutdoorAir()) {
idfObject.setString(AirTerminal_SingleDuct_VAV_ReheatFields::DesignSpecificationOutdoorAirObjectName,
designSpecificationOutdoorAir->name().get());
}
if (auto dsoaOrList_ = getOrCreateThermalZoneDSOA(zone.cast<ThermalZone>())) {
idfObject.setString(AirTerminal_SingleDuct_VAV_ReheatFields::DesignSpecificationOutdoorAirObjectName, dsoaOrList_->nameString());
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,21 @@ namespace energyplus {
}
}

// Extensible Groups for DSOAs are pushed in translateSizingZone to retain order of the file
// Extensible Groups for DSOAs are no longer pushed in translateSizingZone to retain order of the file, because:
// 1) Thermal Zones are translated before AirLoopHVACs, so we guarantee proper order (unless we mess something up, like adding a new always
// translated object early on that will call it)
// 2) Doing it in translateSizingZone means that it will NOT be written if the Sizing:Zone isn't, for eg when you have no design days
// but that is a valid use case
auto oa_controller = modelObject.controllerOutdoorAir();
if (auto oa_sys_ = oa_controller.airLoopHVACOutdoorAirSystem()) {
if (auto a_ = oa_sys_->airLoopHVAC()) {
for (const auto& z : a_->thermalZones()) {
if (auto dsoaOrList_ = getOrCreateThermalZoneDSOA(z)) {
IdfExtensibleGroup eg = idfObject.pushExtensibleGroup({z.nameString(), dsoaOrList_->nameString(), zoneDSZADName(z).value_or("")});
}
}
}
}
Comment on lines +101 to +115
Copy link
Copy Markdown
Collaborator Author

@jmarrec jmarrec Mar 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ControllerMV now fills its own extensible groups.

as you can see, ThermalZone is translated before AirLoopHVAC, and I have no reasons to believe any other object will trigger a weird order where Controller:MechanicalVentilation will end up being translated before the ThermalZone, thus produces a DSOA:SpaceList that is placed BEFORE the thermal zone. The test I added in /src/energyplus/Test/ControllerOutdoorAir_GTest.cpp at least has no IDF change
https://github.com/NREL/OpenStudio/blob/a882f64d0989414b26e18dc071415740ee92c43c/src/energyplus/ForwardTranslator.cpp#L3353-L3474


m_idfObjects.push_back(idfObject);
return boost::optional<IdfObject>(idfObject);
Expand Down
Loading