Skip to content

Commit

Permalink
Merge branch 'develop' into defect9740
Browse files Browse the repository at this point in the history
  • Loading branch information
KarenWGard committed Sep 15, 2023
2 parents 99a7f6a + 8134ee0 commit 5f813c9
Show file tree
Hide file tree
Showing 115 changed files with 5,330 additions and 2,272 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3385,7 +3385,7 @@ \subsubsection{Inputs}

\paragraph{Field: G-Function Reference Ratio}\label{field-g-function-reference-ratio}

The G-Functions may be formulated slightly differently based on the program which generated them. The original g-functions as defined by Eskilson are based on an borehole radius to active length ratio of 0.0005. If the physical ratio is different from this, a correction must be applied. EnergyPlus will apply the correction, based on the reference ratio entered in this field. Therefore, therefore two possible input configurations.
The G-Functions may be formulated slightly differently based on the program which generated them. The original g-functions as defined by Eskilson are based on an borehole radius to active length ratio of 0.0005. If the physical ratio is different from this, a correction must be applied. EnergyPlus will apply the correction, based on the reference ratio entered in this field. Therefore, there are two possible input configurations.

\begin{itemize}
\item
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3114,7 +3114,7 @@ \subsubsection{Surface Inside Face Lights Radiation Heat Gain Rate per Area {[}W

\subsubsection{Surface Inside Face Lights Radiation Heat Gain Energy {[}J{]}}\label{surface-inside-face-lights-radiation-heat-gain-energy-j}

These ``inside face lights radiation heat gain'' output variables describe the heat transferred by shortwave radiation onto the inside face. The values are always positive and indicate heat is being added to the surface's face by shortwave radiation that emanated from electric lighting equipment and was absorbed by the surface. Different versions of the report are available including the basic heat gain rate (W), and a per unit area flux (W/m2), and an energy version (J).
These ``inside face lights radiation heat gain'' output variables describe the heat transferred by shortwave radiation onto the inside face. The values are always positive and indicate heat is being added to the surface's face by shortwave radiation that emanated from electric lighting equipment and was absorbed by the surface. Note that this includes light from other zones that are transmitted through interzone windows. Different versions of the report are available including the basic heat gain rate (W), and a per unit area flux (W/m2), and an energy version (J).

\subsubsection{Surface Inside Face Internal Gains Radiation Heat Gain Rate {[}W{]}}\label{surface-inside-face-internal-gains-radiation-heat-gain-rate-w}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@ \subsubsection{Outputs}\label{outputs-040}
\item
HVAC,Average,Water Heater Total Demand Heat Transfer Rate {[}W{]}
\item
HVAC,Sum,Water Heater Total Demand Energy {[}J{]}
HVAC,Sum,Water Heater Total Demand Heat Transfer Energy {[}J{]}
\item
HVAC,Average,Water Heater Heating Rate {[}W{]}
\item
Expand Down Expand Up @@ -562,7 +562,7 @@ \subsubsection{Outputs}\label{outputs-040}

The average heating rate demanded to maintain the setpoint temperature.

\paragraph{Water Heater Total Demand Energy {[}J{]}}\label{water-heater-total-demand-energy-j}
\paragraph{Water Heater Total Demand Heat Transfer Energy {[}J{]}}\label{water-heater-total-demand-heat-transfer-energy-j}

The heating energy demanded to maintain the setpoint temperature.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1406,15 +1406,15 @@ \subsubsection{Predefined Monthly Summary Reports}\label{predefined-monthly-summ
\begin{itemize}
\item
Water Heater Total Demand Energy (SumOrAverage)
Water Heater Total Demand Heat Transfer Energy (SumOrAverage)
\item
Water Heater Use Side Heat Transfer Energy (SumOrAverage)
\item
Water Heater Burner Heating Energy (SumOrAverage)
\item
Water Heater Gas Consumption (SumOrAverage)
\item
Water Heater Total Demand Energy (HoursNonZero)
Water Heater Total Demand Heat Transfer Energy (HoursNonZero)
\item
Water Heater Loss Demand Energy (SumOrAverage)
\item
Expand Down
14 changes: 10 additions & 4 deletions src/ConvertInputFormat/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ if(BUILD_TESTING)
configure_file(${IDF_FILE} "${TEST_DIR}/1ZoneUncontrolled.idf" COPYONLY)
configure_file(${IDF_FILE} "${TEST_DIR}/1.ZoneUncontrolled.idf" COPYONLY)

add_test(NAME ConvertInputFormat2.RegularFile_AbsolutePath
add_test(NAME ConvertInputFormat.RegularFile_AbsolutePath
COMMAND "${Python_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/test_convert_input_format.py"
--convertinputformat-exe $<TARGET_FILE:ConvertInputFormat>
--out-dir "${TEST_DIR}/RegularFile_AbsolutePath"
--expected-filename 1ZoneUncontrolled.epJSON
--input-file "${TEST_DIR}/1ZoneUncontrolled.idf"
)

add_test(NAME ConvertInputFormat2.RegularFile_RelativePath
add_test(NAME ConvertInputFormat.RegularFile_RelativePath
COMMAND "${Python_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/test_convert_input_format.py"
--convertinputformat-exe $<TARGET_FILE:ConvertInputFormat>
--out-dir "RegularFile_AbsolutePath"
Expand All @@ -53,20 +53,26 @@ if(BUILD_TESTING)
WORKING_DIRECTORY ${TEST_DIR}
)

add_test(NAME ConvertInputFormat2.ExtraDotFile_AbsolutePath
add_test(NAME ConvertInputFormat.ExtraDotFile_AbsolutePath
COMMAND "${Python_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/test_convert_input_format.py"
--convertinputformat-exe $<TARGET_FILE:ConvertInputFormat>
--out-dir "${TEST_DIR}/ExtraDotFile_AbsolutePath"
--expected-filename 1.ZoneUncontrolled.epJSON
--input-file "${TEST_DIR}/1.ZoneUncontrolled.idf"
)

add_test(NAME ConvertInputFormat2.ExtraDotFile__RelativePath
add_test(NAME ConvertInputFormat.ExtraDotFile__RelativePath
COMMAND "${Python_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/test_convert_input_format.py"
--convertinputformat-exe $<TARGET_FILE:ConvertInputFormat>
--out-dir "ExtraDotFile__RelativePath"
--expected-filename 1.ZoneUncontrolled.epJSON
--input-file "1.ZoneUncontrolled.idf"
WORKING_DIRECTORY ${TEST_DIR}
)

add_test(NAME ConvertInputFormat.DDYtoEPJSON
COMMAND ConvertInputFormat --output "${TEST_DIR}/DDY" --format epJSON "${PROJECT_SOURCE_DIR}/../../weather/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.ddy"
)
set_tests_properties(ConvertInputFormat.DDYtoEPJSON PROPERTIES FAIL_REGULAR_EXPRESSION "ERROR;Input file conversion failed")

endif()
43 changes: 27 additions & 16 deletions src/ConvertInputFormat/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ static constexpr std::array<std::string_view, static_cast<int>(OutputTypes::Num)

static constexpr auto outputTypeExperimentalStart = OutputTypes::CBOR;

template <typename... Args> void displayMessage(std::string_view str_format, Args &&...args)
template <typename... Args> void displayMessage(std::string_view str_format, Args &&... args)
{
fmt::print(std::cout, str_format, args...);
std::cout.write("\n", 1);
Expand Down Expand Up @@ -238,12 +238,14 @@ bool checkForUnsupportedObjects(json const &epJSON, bool convertHVACTemplate)
return errorsFound;
}

bool processErrors(std::unique_ptr<IdfParser> const &idf_parser, std::unique_ptr<Validation> const &validation)
bool processErrors(std::unique_ptr<IdfParser> const &idf_parser, std::unique_ptr<Validation> const &validation, bool isDDY)
{
auto const idf_parser_errors = idf_parser->errors();
auto const idf_parser_warnings = idf_parser->warnings();

auto const validation_errors = validation->errors();
bool hasValidationErrors = false;

auto const validation_warnings = validation->warnings();

for (auto const &error : idf_parser_errors) {
Expand All @@ -253,15 +255,20 @@ bool processErrors(std::unique_ptr<IdfParser> const &idf_parser, std::unique_ptr
displayMessage(warning);
}
for (auto const &error : validation_errors) {
if (isDDY) {
if ((error.find("Missing required property 'Building'") != std::string::npos) ||
(error.find("Missing required property 'GlobalGeometryRules'") != std::string::npos)) {
continue;
}
}
hasValidationErrors = true;
displayMessage(error);
}
for (auto const &warning : validation_warnings) {
displayMessage(warning);
}

bool has_errors = validation->hasErrors() || idf_parser->hasErrors();

return has_errors;
return hasValidationErrors || idf_parser->hasErrors();
}

void cleanEPJSON(json &epjson)
Expand Down Expand Up @@ -295,23 +302,24 @@ bool processInput(fs::path const &inputFilePath,

auto const inputFileType = EnergyPlus::FileSystem::getFileType(inputFilePath);

bool const isEpJSON = EnergyPlus::FileSystem::is_all_json_type(inputFileType);
bool const isCBOR = (inputFileType == EnergyPlus::FileSystem::FileTypes::CBOR);
bool const isMsgPack = (inputFileType == EnergyPlus::FileSystem::FileTypes::MsgPack);
bool const isUBJSON = (inputFileType == EnergyPlus::FileSystem::FileTypes::UBJSON);
bool const isBSON = (inputFileType == EnergyPlus::FileSystem::FileTypes::BSON);
const bool isEpJSON = EnergyPlus::FileSystem::is_all_json_type(inputFileType);
const bool isCBOR = (inputFileType == EnergyPlus::FileSystem::FileTypes::CBOR);
const bool isMsgPack = (inputFileType == EnergyPlus::FileSystem::FileTypes::MsgPack);
const bool isUBJSON = (inputFileType == EnergyPlus::FileSystem::FileTypes::UBJSON);
const bool isBSON = (inputFileType == EnergyPlus::FileSystem::FileTypes::BSON);
const bool isIDForIMF = EnergyPlus::FileSystem::is_idf_type(inputFileType); // IDF or IMF
const bool isDDY = (inputFileType == EnergyPlus::FileSystem::FileTypes::DDY);

if (!(isEpJSON || EnergyPlus::FileSystem::is_idf_type(inputFileType))) {
displayMessage("ERROR: Input file must have IDF, IMF, or epJSON extension.");
if (!(isEpJSON || isIDForIMF || isDDY)) {
displayMessage("ERROR: Input file must have IDF, IMF, DDY, or epJSON extension.");
return false;
}

if (outputType == OutputTypes::epJSON &&
(inputFileType == EnergyPlus::FileSystem::FileTypes::EpJSON || inputFileType == EnergyPlus::FileSystem::FileTypes::JSON)) {
displayMessage("Same output format as input format requested (epJSON). Skipping conversion and moving to next file.");
return false;
} else if (outputType == OutputTypes::IDF &&
(inputFileType == EnergyPlus::FileSystem::FileTypes::IDF || inputFileType == EnergyPlus::FileSystem::FileTypes::IMF)) {
} else if (outputType == OutputTypes::IDF && (isIDForIMF || isDDY)) {
displayMessage("Same output format as input format requested (IDF). Skipping conversion and moving to next file.");
return false;
} else if (outputType == OutputTypes::CBOR && isCBOR) {
Expand Down Expand Up @@ -349,8 +357,11 @@ bool processInput(fs::path const &inputFilePath,
return false;
}

bool const is_valid = validation->validate(epJSON);
bool const hasErrors = processErrors(idf_parser, validation);
bool is_valid = validation->validate(epJSON);
bool const hasErrors = processErrors(idf_parser, validation, isDDY);
if (isDDY && !hasErrors) {
is_valid = true;
}
bool const versionMatch = checkVersionMatch(epJSON);
bool const unsupportedFound = checkForUnsupportedObjects(epJSON, convertHVACTemplate);

Expand Down
51 changes: 48 additions & 3 deletions src/EnergyPlus/AirLoopHVACDOAS.cc
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
#include <EnergyPlus/InputProcessing/InputProcessor.hh>
#include <EnergyPlus/MixedAir.hh>
#include <EnergyPlus/NodeInputManager.hh>
#include <EnergyPlus/OutAirNodeManager.hh>
#include <EnergyPlus/PhotovoltaicThermalCollectors.hh>
#include <EnergyPlus/PlantUtilities.hh>
#include <EnergyPlus/Psychrometrics.hh>
Expand Down Expand Up @@ -382,6 +383,7 @@ namespace AirLoopHVACDOAS {

thisSplitter.name = UtilityRoutines::makeUPPER(thisObjectName);
thisSplitter.InletNodeName = UtilityRoutines::makeUPPER(fields.at("inlet_node_name").get<std::string>());
thisSplitter.InletNodeNum = UtilityRoutines::FindItemInList(thisSplitter.InletNodeName, state.dataLoopNodes->NodeID);
thisSplitter.m_AirLoopSplitter_Num = AirLoopSplitterNum - 1;

auto NodeNames = fields.find("nodes");
Expand Down Expand Up @@ -695,6 +697,23 @@ namespace AirLoopHVACDOAS {
ShowSevereError(state, format("Outlet node number is not found in {} = {}", CurrentModuleObject, CompName));
errorsFound = true;
}
// Check node connection to ensure that the outlet node of the previous component is the inlet node of the current component
if (CompNum > 1) {
if (thisOutsideAirSys.InletNodeNum(CompNum) != thisOutsideAirSys.OutletNodeNum(CompNum - 1)) {
ShowSevereError(state,
format("getAirLoopMixer: Node Connection Error in AirLoopHVAC:DedicatedOutdoorAirSystem = {}. Inlet node "
"of {} as current component is not same as the outlet node of "
"{} as previous component",
thisDOAS.Name,
thisOutsideAirSys.ComponentName(CompNum),
thisOutsideAirSys.ComponentName(CompNum - 1)));
ShowContinueError(state,
format("The inlet node name = {}, and the outlet node name = {}.",
state.dataLoopNodes->NodeID(thisOutsideAirSys.InletNodeNum(CompNum)),
state.dataLoopNodes->NodeID(thisOutsideAirSys.OutletNodeNum(CompNum - 1))));
errorsFound = true;
}
}
}

thisDOAS.m_InletNodeNum = thisOutsideAirSys.InletNodeNum(1);
Expand Down Expand Up @@ -782,6 +801,27 @@ namespace AirLoopHVACDOAS {

thisDOAS.m_AirLoopDOASNum = AirLoopDOASNum - 1;
state.dataAirLoopHVACDOAS->airloopDOAS.push_back(thisDOAS);

if (!OutAirNodeManager::CheckOutAirNodeNumber(state, thisDOAS.m_InletNodeNum)) {
ShowSevereError(state,
format("Inlet node ({}) is not one of OutdoorAir:Node in {} = {}",
state.dataLoopNodes->NodeID(thisDOAS.m_InletNodeNum),
CurrentModuleObject,
thisDOAS.Name));
errorsFound = true;
}

// Ensure the outlet node is the splitter inlet node, otherwise issue a severe error
if (thisDOAS.m_OutletNodeNum != thisDOAS.m_CompPointerAirLoopSplitter->InletNodeNum) {
ShowSevereError(
state,
format("The outlet node is not the inlet node of AirLoopHVAC:Splitter in {} = {}", CurrentModuleObject, thisDOAS.Name));
ShowContinueError(state,
format("The outlet node name is {}, and the inlet node name of AirLoopHVAC:Splitter is {}",
state.dataLoopNodes->NodeID(thisDOAS.m_OutletNodeNum),
state.dataLoopNodes->NodeID(thisDOAS.m_CompPointerAirLoopSplitter->InletNodeNum)));
errorsFound = true;
}
}

// Check valid OA controller
Expand Down Expand Up @@ -896,9 +936,14 @@ namespace AirLoopHVACDOAS {

this->m_CompPointerAirLoopMixer->CalcAirLoopMixer(state);
if (this->m_FanIndex > -1) {
state.dataLoopNodes->Node(this->m_FanInletNodeNum).MassFlowRateMaxAvail = this->SumMassFlowRate;
state.dataLoopNodes->Node(this->m_FanOutletNodeNum).MassFlowRateMaxAvail = this->SumMassFlowRate;
state.dataLoopNodes->Node(this->m_FanOutletNodeNum).MassFlowRateMax = this->SumMassFlowRate;
if (this->m_FanInletNodeNum == this->m_InletNodeNum) {
state.dataLoopNodes->Node(this->m_FanInletNodeNum).MassFlowRateMaxAvail = this->SumMassFlowRate;
state.dataLoopNodes->Node(this->m_FanOutletNodeNum).MassFlowRateMaxAvail = this->SumMassFlowRate;
state.dataLoopNodes->Node(this->m_FanOutletNodeNum).MassFlowRateMax = this->SumMassFlowRate;
} else {
state.dataLoopNodes->Node(this->m_InletNodeNum).MassFlowRateMax = this->SumMassFlowRate;
state.dataLoopNodes->Node(this->m_InletNodeNum).MassFlowRateMaxAvail = this->SumMassFlowRate;
}
}
ManageOutsideAirSystem(state, this->OASystemName, FirstHVACIteration, 0, this->m_OASystemNum);
Real64 Temp = state.dataLoopNodes->Node(this->m_OutletNodeNum).Temp;
Expand Down
1 change: 1 addition & 0 deletions src/EnergyPlus/AirLoopHVACDOAS.hh
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ namespace AirLoopHVACDOAS {
std::vector<std::string> OutletNodeName;
std::vector<int> OutletNodeNum;
Real64 InletTemp = 0.0;
int InletNodeNum = 0;

static void getAirLoopSplitter(EnergyPlusData &state);
void CalcAirLoopSplitter(EnergyPlusData &state, Real64 Temp, Real64 Humrat);
Expand Down
Loading

5 comments on commit 5f813c9

@nrel-bot
Copy link

Choose a reason for hiding this comment

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

defect9740 (KarenWGard) - Win64-Windows-10-VisualStudio-16: OK (2734 of 2734 tests passed, 0 test warnings)

Build Badge Test Badge

@nrel-bot-2b
Copy link

Choose a reason for hiding this comment

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

defect9740 (KarenWGard) - x86_64-Linux-Ubuntu-22.04-gcc-11.4: OK (3560 of 3560 tests passed, 4 test warnings)

Messages:\n

  • 3 tests had: BND diffs.
  • 1 test had: ERR diffs.
  • 1 test had: Table small diffs.

Build Badge Test Badge

@nrel-bot-3
Copy link

Choose a reason for hiding this comment

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

defect9740 (KarenWGard) - x86_64-MacOS-10.17-clang-14.0.0: OK (3519 of 3519 tests passed, 3 test warnings)

Messages:\n

  • 3 tests had: BND diffs.
  • 1 test had: ERR diffs.

Build Badge Test Badge

@nrel-bot-2b
Copy link

Choose a reason for hiding this comment

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

defect9740 (KarenWGard) - x86_64-Linux-Ubuntu-22.04-gcc-11.4-UnitTestsCoverage-Debug: OK (1949 of 1949 tests passed, 0 test warnings)

Build Badge Test Badge Coverage Badge

@nrel-bot-2b
Copy link

Choose a reason for hiding this comment

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

defect9740 (KarenWGard) - x86_64-Linux-Ubuntu-22.04-gcc-11.4-IntegrationCoverage-Debug: OK (788 of 788 tests passed, 0 test warnings)

Build Badge Test Badge Coverage Badge

Please sign in to comment.