Skip to content
Open
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
52503e8
Initial commit
Apr 11, 2026
1ddc567
Fix some unit tests
Apr 11, 2026
1ca4b76
Fix first issue
Apr 15, 2026
d9ad532
Forgot to add/commit .hh file
Apr 16, 2026
c59795d
Fix a few more issues
Apr 17, 2026
cf33963
Fix more unit tests
Apr 18, 2026
dc338d5
Fix more unit tests
Apr 18, 2026
0a5070f
Fix yet more unit tests
Apr 19, 2026
4260454
Fix still more unit tests
Apr 22, 2026
9fc6e17
Forgot to add a file
Apr 22, 2026
abb2299
Merge develop, fix more unit tests
Apr 25, 2026
8507a61
Fix a few more unit tests
Apr 26, 2026
e11d842
Fix EnergyPlusFixture.AirflowNetwork_TestFanModel
jasondegraw May 11, 2026
3554729
Fix AirflowNetwork_UserDefinedDuctViewFactors
jasondegraw May 11, 2026
8d28919
Fix the AFN duct sizing test
jasondegraw May 12, 2026
3738b27
Possible fix of final AFN test
jasondegraw May 13, 2026
7652af7
Fix? 3 of 4 unit tests
rraustad Jun 18, 2026
09e445d
Fix more unit tests
rraustad Jun 18, 2026
d27b11e
Of course the coil was already read in init_state
rraustad Jun 18, 2026
89a5c56
Merge branch 'develop' of https://github.com/NatLabRockies/EnergyPlus…
rraustad Jun 18, 2026
dcb8b45
Fix more unit tests, all unit tests pass locally
rraustad Jun 19, 2026
c75d9e1
Merge branch 'develop' into CoilAPI2
mitchute Jun 22, 2026
f06cd9f
format
mitchute Jun 22, 2026
28bdcb3
Merge branch 'develop' into CoilAPI2
mitchute Jul 2, 2026
36a3756
pull meter resizing into a function so it can be reused, so we don't …
mitchute Jul 2, 2026
13b803c
Merge branch 'develop' into CoilAPI2
mitchute Jul 2, 2026
1021a14
hack to let init_state happen before the branches have been setup
mitchute Jul 2, 2026
67efbe4
Revert "hack to let init_state happen before the branches have been s…
mitchute Jul 2, 2026
22e7b66
more fun with branch initialization
mitchute Jul 2, 2026
a0ee495
some work to let coil be read in before the branch inputs have been c…
mitchute Jul 3, 2026
7a26972
another setup patch
mitchute Jul 5, 2026
063c08b
a few more cleanups
mitchute Jul 6, 2026
1a95bb0
patch tests to use a helper function to clear the state and reattache…
mitchute Jul 6, 2026
aee7a8b
add a few comments
mitchute Jul 6, 2026
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
42 changes: 25 additions & 17 deletions idd/embedded/generate_embeddable_epJSON_schema.cpp
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
#include <cstdint> // std::uint8_t
#include <fstream> // std::ifstream
#include <cstdint> // std::uint8_t
#include <fstream> // std::ifstream
Comment on lines +1 to +2

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'm not sure where these changes came from. Most of it is formatting, but develop is merged in, and this looks like part of the EnergyPlus::format conversion work. Probably safe to ignore.

#include <stdexcept>
#include <vector> // std::vector
#include <vector> // std::vector
#ifndef __cppcheck__
# if __has_include(<filesystem>)
# include <filesystem>
#if __has_include(<filesystem>)
#include <filesystem>
namespace fs = std::filesystem;
# elif __has_include(<experimental/filesystem>)
# include <experimental/filesystem>
#elif __has_include(<experimental/filesystem>)
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
# else
#else
// cppcheck-suppress preprocessorErrorDirective
# error "no filesystem support"
# endif
#error "no filesystem support"
#endif
#endif

#include <nlohmann/json.hpp> // json
#include <EnergyPlus/Formatters.hh>
#include <nlohmann/json.hpp> // json

using json = nlohmann::json;

Expand Down Expand Up @@ -98,9 +98,12 @@ static constexpr auto footer = R"cpp(
} // namespace EnergyPlus
)cpp";

int main(int argc, char const* argv[]) {
int main(int argc, char const *argv[]) {
if (argc != 3) {
EnergyPlus::print(stderr, "usage: ./generate_embeddable_schema path/to/Energy+.schema.epJSON path/to/EmbeddedEpJSONSchema.cc\n");
EnergyPlus::print(
stderr,
"usage: ./generate_embeddable_schema path/to/Energy+.schema.epJSON "
"path/to/EmbeddedEpJSONSchema.cc\n");
return 1;
}

Expand All @@ -117,22 +120,27 @@ int main(int argc, char const* argv[]) {
const fs::path outFilePath(argv[2]);
const auto outFileDir = outFilePath.parent_path();
if (!fs::is_directory(outFileDir)) {
EnergyPlus::print(stderr, "Output Directory does not exist: {}\n", outFileDir.generic_string());
EnergyPlus::print(stderr, "Output Directory does not exist: {}\n",
outFileDir.generic_string());
fs::create_directory(outFileDir);
}

std::FILE* outfile = std::fopen(argv[2], "w");
std::FILE *outfile = std::fopen(argv[2], "w");
if (outfile == nullptr) {
EnergyPlus::print(stderr, "Could not open output file: {}\n", argv[2]);
return 1;
}

EnergyPlus::print(outfile, "{}", header);

EnergyPlus::print(outfile, " static constexpr std::array< std::uint8_t, {} > embeddedSchema = {{{{\n", v_cbor.size());
EnergyPlus::print(outfile,
" static constexpr std::array< std::uint8_t, {} > "
"embeddedSchema = {{{{\n",
v_cbor.size());

for (size_t i = 0; i < v_cbor.size(); ++i) {
EnergyPlus::print(outfile, "{:#04x},", v_cbor[i]); // Format the std::uint8_t as hex
EnergyPlus::print(outfile, "{:#04x},",
v_cbor[i]); // Format the std::uint8_t as hex
if (i % 40 == 0 && i != 0) {
EnergyPlus::print(outfile, "\n");
}
Expand Down
20 changes: 20 additions & 0 deletions src/EnergyPlus/AirflowNetwork/src/Solver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12640,6 +12640,7 @@ namespace AirflowNetwork {
DuctSizingSBFlag = true;
}
while (NodeNum1 != NodeSplitter) {
bool foundNextDuct = false;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Added this boolean as part of a trapdoor to prevent an infinite loop failure. This came up in one of the failing unit tests, it then failed more normally, but the approach itself is risky.

for (AFNLinkNum1 = 1; AFNLinkNum1 <= AirflowNetworkNumOfLinks; AFNLinkNum1++) {
if (NodeNum1 != AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0]) {
continue;
Expand All @@ -12659,10 +12660,14 @@ namespace AirflowNetwork {
DynamicLoss += disSysCompDuct.TurDynCoef;
NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1];
DuctSizingSTFlag = true;
foundNextDuct = true;
break;
}
}
}
if (!foundNextDuct) {
break;
}
}
}
if (DuctSizingSTFlag) {
Expand Down Expand Up @@ -12761,6 +12766,7 @@ namespace AirflowNetwork {
DuctSizingSBFlag = true;
}
while (NodeNum1 != NodeSplitter) {
bool foundNextDuct = false;
for (AFNLinkNum1 = 1; AFNLinkNum1 <= AirflowNetworkNumOfLinks; AFNLinkNum1++) {
if (NodeNum1 != AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1]) {
continue;
Expand All @@ -12780,10 +12786,14 @@ namespace AirflowNetwork {
DynamicLoss += disSysCompDuct.TurDynCoef;
NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0];
DuctSizingSBFlag = true;
foundNextDuct = true;
break;
}
}
}
if (!foundNextDuct) {
break;
}
}
}
if (DuctSizingSBFlag) {
Expand Down Expand Up @@ -12886,6 +12896,7 @@ namespace AirflowNetwork {
DuctSizingRTFlag = true;
}
while (NodeNum1 != NodeMixer) {
bool foundNextDuct = false;
for (AFNLinkNum1 = 1; AFNLinkNum1 <= AirflowNetworkNumOfLinks; AFNLinkNum1++) {
if (NodeNum1 != AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1]) {
continue;
Expand All @@ -12905,10 +12916,14 @@ namespace AirflowNetwork {
DynamicLoss += disSysCompDuct.TurDynCoef;
NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0];
DuctSizingRTFlag = true;
foundNextDuct = true;
break;
}
}
}
if (!foundNextDuct) {
break;
}
}
}
if (DuctSizingRTFlag) {
Expand Down Expand Up @@ -13009,6 +13024,7 @@ namespace AirflowNetwork {
DuctSizingRBFlag = true;
}
while (NodeNum1 != NodeMixer) {
bool foundNextDuct = false;
for (AFNLinkNum1 = 1; AFNLinkNum1 <= AirflowNetworkNumOfLinks; AFNLinkNum1++) {
if (NodeNum1 != AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[0]) {
continue;
Expand All @@ -13028,10 +13044,14 @@ namespace AirflowNetwork {
DynamicLoss += disSysCompDuct.TurDynCoef;
NodeNum1 = AirflowNetworkLinkageData(AFNLinkNum1).NodeNums[1];
DuctSizingRBFlag = true;
foundNextDuct = true;
break;
}
}
}
if (!foundNextDuct) {
break;
}
}
}
if (DuctSizingRBFlag) {
Expand Down
1 change: 0 additions & 1 deletion src/EnergyPlus/BranchInputManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1085,7 +1085,6 @@ namespace BranchInputManager {
cNumericFields.deallocate();
lAlphaBlanks.deallocate();
lNumericBlanks.deallocate();
Node::TestInletOutletNodes(state);
state.dataBranchInputManager->GetBranchInputOneTimeFlag = false;
}
}
Expand Down
133 changes: 24 additions & 109 deletions src/EnergyPlus/BranchNodeConnections.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2039,6 +2039,16 @@ void SetUpCompSets(EnergyPlusData &state,
Node::ConnectionObjectType ComponentTypeEnum = static_cast<Node::ConnectionObjectType>(getEnumValue(ConnectionObjectTypeNamesUC, CompTypeUC));
assert(ComponentTypeEnum != Node::ConnectionObjectType::Invalid);

auto const compSetSource = [&]() {
if (ParentTypeEnum == Node::ConnectionObjectType::Undefined) {
return Node::CompSetSource::ComponentRegistration;
}
if (ParentTypeEnum == Node::ConnectionObjectType::Branch) {
return Node::CompSetSource::BranchTopology;
}
return Node::CompSetSource::ParentChild;
}();
Comment on lines +2042 to +2053

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Another helper to work out branch connections.


int Found = 0;

// See if Component-Nodes set is already there - should be unique
Expand Down Expand Up @@ -2080,123 +2090,21 @@ void SetUpCompSets(EnergyPlusData &state,
if (!Description.empty()) {
state.dataBranchNodeConnections->CompSets(Count).Description = Description;
}
state.dataBranchNodeConnections->CompSets(Count).Source = compSetSource;
Found = Count;
break;
}
}
if (Found == 0) {
for (int Count = 1; Count <= state.dataBranchNodeConnections->NumCompSets; ++Count) {
Found = 0;
// Test if inlet node has been used before as an inlet node
// If the matching node name does not belong to the parent object, then error
// For example a fan may share the same inlet node as the furnace object which is its parent
if (InletNode != state.dataBranchNodeConnections->CompSets(Count).InletNodeName) {
continue;
// If parent type is undefined then no error
}
if ((ParentTypeEnum == Node::ConnectionObjectType::Undefined) ||
(state.dataBranchNodeConnections->CompSets(Count).ParentObjectType == Node::ConnectionObjectType::Undefined)) {
// If node name is undefined then no error
} else if (InletNode != undefined) {
// If the matching node name does not belong to the parent or child object, then error
// For example a fan may share the same inlet node as the furnace object which is its parent
if ((ParentTypeEnum == state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType) &&
(ParentName == state.dataBranchNodeConnections->CompSets(Count).CName)) {
// OK - The duplicate inlet node belongs to this component's parent
} else if ((ComponentTypeEnum == state.dataBranchNodeConnections->CompSets(Count).ParentObjectType) &&
Comment on lines -2095 to -2106

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

There's a lot of if-then-else in this block that has been removed. I think all of the paths are accounted for now, but this in particular needs a careful review.

(CompName == state.dataBranchNodeConnections->CompSets(Count).ParentCName)) {
// OK - The duplicate inlet node belongs to a child of this component
} else {
// Due to possibility of grandparents or more, if the matching node name
// belongs to a component that appears as a parent, then OK
int Found2 = 0;
for (int Count2 = 1; Count2 <= state.dataBranchNodeConnections->NumCompSets; ++Count2) {
if ((state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType ==
state.dataBranchNodeConnections->CompSets(Count2).ParentObjectType) &&
(state.dataBranchNodeConnections->CompSets(Count).CName ==
state.dataBranchNodeConnections->CompSets(Count2).ParentCName)) {
Found2 = 1;
}
if ((ComponentTypeEnum == state.dataBranchNodeConnections->CompSets(Count2).ParentObjectType) &&
(CompName == state.dataBranchNodeConnections->CompSets(Count2).ParentCName)) {
Found2 = 1;
}
}
if (Found2 == 0) {
ShowWarningError(state, std::format("Node used as an inlet more than once: {}", InletNode));
ShowContinueError(
state,
std::format(
" Used by: {}, name={}",
ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Count).ParentObjectType)],
state.dataBranchNodeConnections->CompSets(Count).ParentCName));
ShowContinueError(
state,
std::format(
" as inlet for: {}, name={}",
ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType)],
state.dataBranchNodeConnections->CompSets(Count).CName));
ShowContinueError(state, std::format("{}{}{}", " and by : ", ParentTypeUC + ", name=", ParentName));
ShowContinueError(state, std::format("{}{}{}", " as inlet for: ", CompTypeUC + ", name=", CompName));
}
}
}
// Test if outlet node has been used before as an outlet node
// If the matching node name does not belong to the parent or child object, then error
// For example a fan may share the same outlet node as the furnace object which is its parent
if (OutletNode != state.dataBranchNodeConnections->CompSets(Count).OutletNodeName) {
continue;
// If parent type is undefined then no error
}
if ((ParentTypeEnum == Node::ConnectionObjectType::Undefined) ||
(state.dataBranchNodeConnections->CompSets(Count).ParentObjectType == Node::ConnectionObjectType::Undefined)) {
// If node name is undefined then no error
} else if (OutletNode != undefined) {
if ((ParentTypeEnum == state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType) &&
(ParentName == state.dataBranchNodeConnections->CompSets(Count).CName)) {
// OK - The duplicate outlet node belongs to this component's parent
} else if ((ComponentTypeEnum == state.dataBranchNodeConnections->CompSets(Count).ParentObjectType) &&
(CompName == state.dataBranchNodeConnections->CompSets(Count).ParentCName)) {
// OK - The duplicate outlet node belongs to a child of this component
} else {
// Due to possibility of grandparents or more, if the matching node name
// belongs to a component that appears as a parent, then OK
int Found2 = 0;
for (int Count2 = 1; Count2 <= state.dataBranchNodeConnections->NumCompSets; ++Count2) {
if ((state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType ==
state.dataBranchNodeConnections->CompSets(Count2).ParentObjectType) &&
(state.dataBranchNodeConnections->CompSets(Count).CName ==
state.dataBranchNodeConnections->CompSets(Count2).ParentCName)) {
Found2 = 1;
}
if ((ComponentTypeEnum == state.dataBranchNodeConnections->CompSets(Count2).ParentObjectType) &&
(CompName == state.dataBranchNodeConnections->CompSets(Count2).ParentCName)) {
Found2 = 1;
}
}
// This rule is violated by dual duct units, so let it pass
if (Found2 == 0) {
std::string_view const CType =
ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType)];
if ((!has_prefixi(CType, "AirTerminal:DualDuct:")) && (!has_prefixi(CompTypeUC, "AirTerminal:DualDuct:"))) {
ShowWarningError(state, std::format("Node used as an outlet more than once: {}", OutletNode));
ShowContinueError(
state,
std::format(
" Used by: {}, name={}",
ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Count).ParentObjectType)],
state.dataBranchNodeConnections->CompSets(Count).ParentCName));
ShowContinueError(
state,
std::format(
" as outlet for: {}, name={}",
ConnectionObjectTypeNames[static_cast<int>(state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType)],
state.dataBranchNodeConnections->CompSets(Count).CName));
ShowContinueError(state, std::format("{}{}{}", " and by : ", ParentTypeUC + ", name=", ParentName));
ShowContinueError(state, std::format("{}{}{}", " as outlet for: ", CompTypeUC + ", name=", CompName));
}
}
}
}
if (compSetSource != state.dataBranchNodeConnections->CompSets(Count).Source) {
continue;
}
if (ComponentTypeEnum != state.dataBranchNodeConnections->CompSets(Count).ComponentObjectType &&
ComponentTypeEnum != Node::ConnectionObjectType::Undefined) {
Expand Down Expand Up @@ -2227,6 +2135,7 @@ void SetUpCompSets(EnergyPlusData &state,
} else {
state.dataBranchNodeConnections->CompSets(state.dataBranchNodeConnections->NumCompSets).Description = undefined;
}
state.dataBranchNodeConnections->CompSets(state.dataBranchNodeConnections->NumCompSets).Source = compSetSource;
}
}

Expand All @@ -2243,11 +2152,14 @@ void TestInletOutletNodes(EnergyPlusData &state)

Array1D_bool AlreadyNoted;

// Test component sets created by branches
// Test component sets created by branch input only.
AlreadyNoted.dimension(state.dataBranchNodeConnections->NumCompSets, false);
for (int Count = 1; Count <= state.dataBranchNodeConnections->NumCompSets; ++Count) {
if (state.dataBranchNodeConnections->CompSets(Count).Source != Node::CompSetSource::BranchTopology) {
continue;
}
for (int Other = 1; Other <= state.dataBranchNodeConnections->NumCompSets; ++Other) {
if (Count == Other) {
if (Count == Other || state.dataBranchNodeConnections->CompSets(Other).Source != Node::CompSetSource::BranchTopology) {
continue;
}
if (state.dataBranchNodeConnections->CompSets(Count).InletNodeName != state.dataBranchNodeConnections->CompSets(Other).InletNodeName) {
Expand Down Expand Up @@ -2290,8 +2202,11 @@ void TestInletOutletNodes(EnergyPlusData &state)

AlreadyNoted = false;
for (int Count = 1; Count <= state.dataBranchNodeConnections->NumCompSets; ++Count) {
if (state.dataBranchNodeConnections->CompSets(Count).Source != Node::CompSetSource::BranchTopology) {
continue;
}
for (int Other = 1; Other <= state.dataBranchNodeConnections->NumCompSets; ++Other) {
if (Count == Other) {
if (Count == Other || state.dataBranchNodeConnections->CompSets(Other).Source != Node::CompSetSource::BranchTopology) {
continue;
}
if (state.dataBranchNodeConnections->CompSets(Count).OutletNodeName != state.dataBranchNodeConnections->CompSets(Other).OutletNodeName) {
Expand Down
Loading
Loading