Skip to content

Commit

Permalink
Merge branch 'develop' into 10065ChillerHeaterFix
Browse files Browse the repository at this point in the history
  • Loading branch information
RKStrand committed Jul 26, 2024
2 parents 818e8dd + 18f5c3f commit 2fa11f3
Show file tree
Hide file tree
Showing 66 changed files with 2,040 additions and 653 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ \subsubsection{Inputs}\label{inputs-004}

\paragraph{Field: Allow Unsupported Zone Equipment}\label{allow-unsupported-zone-equipment}

This is an optional field. Input is Yes or No. The default is No. Set this input to Yes to have zone equipment that are currently unsupported in the AirflowNetwork model allowed in the simulation. Setting this field to Yes, allows the following equipment to be modeled along an AirflowNetwork model: ZoneHVAC:Dehumidifier, ZoneHVAC:EnergyRecoveryVentilator, WaterHeater:HeatPump:*. The AirflowNetwork model will exclude mass balance in these equipment objects and assume the mass flows are self-balanced in the equipment objects.
This is an optional field. Input is Yes or No. The default is No. Set this input to Yes to have zone equipment that are currently unsupported in the AirflowNetwork model allowed in the simulation. Setting this field to Yes, allows the following equipment to be modeled along an AirflowNetwork model: ZoneHVAC:Dehumidifier, ZoneHVAC:EnergyRecoveryVentilator, WaterHeater:HeatPump:*, and ZoneHVAC:WindowAirConditioner. The AirflowNetwork model will exclude mass balance in these equipment objects and assume the mass flows are self-balanced in the equipment objects.

\paragraph{Field: Do Distribution Duct Sizing Calculation}\label{do-distribution-duct-sizing-calculation}

Expand Down
6 changes: 4 additions & 2 deletions idd/Energy+.idd.in
Original file line number Diff line number Diff line change
Expand Up @@ -21309,7 +21309,8 @@ RoomAir:Node:AirflowNetwork:HVACEquipment,
\key ZoneHVAC:IdealLoadsAirSystem
\key ZoneHVAC:RefrigerationChillerSet
\key Fan:ZoneExhaust
\key WaterHeater:HeatPump
\key WaterHeater:HeatPump:PumpedCondenser
\key WaterHeater:HeatPump:WrappedCondenser
\key AirTerminal:DualDuct:ConstantVolume
\key AirTerminal:DualDuct:VAV
\key AirTerminal:SingleDuct:ConstantVolume:Reheat
Expand Down Expand Up @@ -21359,7 +21360,8 @@ RoomAir:Node:AirflowNetwork:HVACEquipment,
\key ZoneHVAC:IdealLoadsAirSystem
\key ZoneHVAC:RefrigerationChillerSet
\key Fan:ZoneExhaust
\key WaterHeater:HeatPump
\key WaterHeater:HeatPump:PumpedCondenser
\key WaterHeater:HeatPump:WrappedCondenser
\key AirTerminal:DualDuct:ConstantVolume
\key AirTerminal:DualDuct:VAV
\key AirTerminal:SingleDuct:ConstantVolume:Reheat
Expand Down
14 changes: 14 additions & 0 deletions src/EnergyPlus/AirflowNetwork/src/Solver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
#include <EnergyPlus/ThermalComfort.hh>
#include <EnergyPlus/UtilityRoutines.hh>
#include <EnergyPlus/WaterThermalTanks.hh>
#include <EnergyPlus/WindowAC.hh>
#include <EnergyPlus/ZoneDehumidifier.hh>
#include <EnergyPlus/ZoneTempPredictorCorrector.hh>

Expand Down Expand Up @@ -10143,6 +10144,7 @@ namespace AirflowNetwork {
using SplitterComponent::GetSplitterNodeNumbers;
using SplitterComponent::GetSplitterOutletNumber;
using WaterThermalTanks::GetHeatPumpWaterHeaterNodeNumber;
using WindowAC::GetWindowACNodeNumber;
using ZoneDehumidifier::GetZoneDehumidifierNodeNumber;

// SUBROUTINE PARAMETER DEFINITIONS:
Expand All @@ -10161,6 +10163,7 @@ namespace AirflowNetwork {

bool HPWHFound(false); // Flag for HPWH identification
bool StandaloneERVFound(false); // Flag for Standalone ERV (ZoneHVAC:EnergyRecoveryVentilator) identification
bool WindowACFound(false); // Flag for Window AC (ZoneHVAC:WindowAirConditioner) identification

// Validate supply and return connections
NodeFound.dimension(m_state.dataLoopNodes->NumOfNodes, false);
Expand Down Expand Up @@ -10273,6 +10276,12 @@ namespace AirflowNetwork {
NodeFound(i) = true;
StandaloneERVFound = true;
}

// Skip Window AC with no OA
if (GetWindowACNodeNumber(m_state, i)) {
NodeFound(i) = true;
WindowACFound = true;
}
}

for (int zoneNum = 1; zoneNum <= m_state.dataGlobal->NumOfZones; ++zoneNum) {
Expand Down Expand Up @@ -10413,6 +10422,11 @@ namespace AirflowNetwork {
format(RoutineName) + "A ZoneHVAC:EnergyRecoveryVentilator is simulated along with an AirflowNetwork but is not "
"included in the AirflowNetwork.");
}
if (WindowACFound) {
ShowWarningError(m_state,
format(RoutineName) + "A ZoneHVAC:WindowAirConditioner is simulated along with an AirflowNetwork but is not "
"included in the AirflowNetwork.");
}
NodeFound.deallocate();

// Assign AirLoop Number to every node and linkage
Expand Down
5 changes: 3 additions & 2 deletions src/EnergyPlus/ChillerElectricASHRAE205.cc
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
#include <EnergyPlus/EMSManager.hh>
#include <EnergyPlus/EnergyPlusLogger.hh>
#include <EnergyPlus/FaultsManager.hh>
#include <EnergyPlus/FileSystem.hh>
#include <EnergyPlus/FluidProperties.hh>
#include <EnergyPlus/General.hh>
#include <EnergyPlus/GeneralRoutines.hh>
Expand Down Expand Up @@ -146,9 +147,9 @@ void getChillerASHRAE205Input(EnergyPlusData &state)
// Since logger context must persist across all calls to libtk205/btwxt, it must be a member
thisChiller.LoggerContext = {&state, format("{} \"{}\"", state.dataIPShortCut->cCurrentModuleObject, thisObjectName)};
thisChiller.Representation = std::dynamic_pointer_cast<tk205::rs0001_ns::RS0001>(
RSInstanceFactory::create("RS0001", rep_file_path.string().c_str(), std::make_shared<EnergyPlusLogger>()));
RSInstanceFactory::create("RS0001", FileSystem::toString(rep_file_path).c_str(), std::make_shared<EnergyPlusLogger>()));
if (nullptr == thisChiller.Representation) {
ShowSevereError(state, format("{} is not an instance of an ASHRAE205 Chiller.", rep_file_path.string()));
ShowSevereError(state, format("{} is not an instance of an ASHRAE205 Chiller.", rep_file_path));
ErrorsFound = true;
}
thisChiller.Representation->performance.performance_map_cooling.get_logger()->set_message_context(&thisChiller.LoggerContext);
Expand Down
81 changes: 51 additions & 30 deletions src/EnergyPlus/CommandLineInterface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,26 @@ Built on Platform: {}
->required(false)
->check(CLI::ExistingFile);

bool debugCLI = false;
// Catching it myself, so I can print the arguments vector before it's mutated
bool debugCLI = std::any_of(args.begin(), args.end(), [](const auto &arg) { return arg == "--debug-cli"; });
if (debugCLI) {
{
fmt::print("ProcessArgs: received args\n");
int na = 0;
for (const auto &a : args) {
fmt::print("* {}: '{}'\n", na++, a);
}
}
{
fmt::print("\nAfter massaging/expanding of args\n");
int na = 0;
for (const auto &a : arguments) {
fmt::print("* {}: '{}'\n", na++, a);
}
}
fmt::print("\n");
}
// bool debugCLI = false;
app.add_flag("--debug-cli", debugCLI, "Print the result of the CLI assignments to the console and exit")->group(""); // Empty group to hide it

app.footer("Example: energyplus -w weather.epw -r input.idf");
Expand Down Expand Up @@ -242,8 +261,8 @@ Built on Platform: {}
R"debug(
state.dataGlobal->AnnualSimulation = {},
state.dataGlobal->DDOnlySimulation = {},
state.dataStrGlobals->outDirPath = '{}',
state.dataStrGlobals->inputIddFilePath= '{}',
state.dataStrGlobals->outDirPath = '{:g}',
state.dataStrGlobals->inputIddFilePath= '{:g}',
runEPMacro = {},
prefixOutName = {},
Expand All @@ -255,13 +274,13 @@ state.dataGlobal->outputEpJSONConversionOnly={},
suffixType={},
state.dataGlobal->numThread={},
state.files.inputWeatherFilePath.filePath='{}',
state.dataStrGlobals->inputFilePath='{}',
state.files.inputWeatherFilePath.filePath='{:g}',
state.dataStrGlobals->inputFilePath='{:g}',
)debug",
state.dataGlobal->AnnualSimulation,
state.dataGlobal->DDOnlySimulation,
state.dataStrGlobals->outDirPath.generic_string(),
state.dataStrGlobals->inputIddFilePath.generic_string(),
state.dataStrGlobals->outDirPath,
state.dataStrGlobals->inputIddFilePath,

runEPMacro,
prefixOutName,
Expand All @@ -270,8 +289,11 @@ state.dataStrGlobals->inputFilePath='{}',
state.dataGlobal->outputEpJSONConversionOnly,
suffixType,
state.dataGlobal->numThread,
state.files.inputWeatherFilePath.filePath.generic_string(),
state.dataStrGlobals->inputFilePath.generic_string());
state.files.inputWeatherFilePath.filePath,
state.dataStrGlobals->inputFilePath);

fmt::print(stderr, "--debug-cli passed: exiting early\n");

exit(0);
}

Expand Down Expand Up @@ -307,8 +329,7 @@ state.dataStrGlobals->inputFilePath='{}',
break;
default:
DisplayString(state,
fmt::format("ERROR: Input file must have IDF, IMF, or epJSON extension: {}",
state.dataStrGlobals->inputFilePath.generic_string()));
fmt::format("ERROR: Input file must have IDF, IMF, or epJSON extension: {:g}", state.dataStrGlobals->inputFilePath));
if (eplusRunningViaAPI) {
return static_cast<int>(ReturnCodes::Failure);
} else {
Expand Down Expand Up @@ -390,7 +411,7 @@ state.dataStrGlobals->inputFilePath='{}',

// Helper to construct output file path
auto composePath = [&outputFilePrefixFullPath](const std::string &suffix) -> fs::path {
return fs::path(outputFilePrefixFullPath.string() + suffix);
return FileSystem::appendSuffixToPath(outputFilePrefixFullPath, suffix);
};

// EnergyPlus files
Expand Down Expand Up @@ -505,7 +526,7 @@ state.dataStrGlobals->inputFilePath='{}',
if (FileSystem::fileExists(state.files.iniFile.filePath)) {
EnergyPlus::InputFile iniFile = state.files.iniFile.try_open();
if (!iniFile.good()) {
DisplayString(state, "ERROR: Could not open file " + iniFile.filePath.string() + " for input (read).");
DisplayString(state, fmt::format("ERROR: Could not open file {} for input (read).", iniFile.filePath));
if (eplusRunningViaAPI) {
return static_cast<int>(ReturnCodes::Failure);
} else {
Expand All @@ -532,7 +553,7 @@ state.dataStrGlobals->inputFilePath='{}',
// Check if specified files exist
if (!FileSystem::fileExists(state.dataStrGlobals->inputFilePath)) {
DisplayString(
state, "ERROR: Could not find input data file: " + FileSystem::getAbsolutePath(state.dataStrGlobals->inputFilePath).string() + ".");
state, fmt::format("ERROR: Could not find input data file: {}.", FileSystem::getAbsolutePath(state.dataStrGlobals->inputFilePath)));
DisplayString(state, errorFollowUp);
if (eplusRunningViaAPI) {
return static_cast<int>(ReturnCodes::Failure);
Expand All @@ -545,7 +566,7 @@ state.dataStrGlobals->inputFilePath='{}',
if (!FileSystem::fileExists(state.files.inputWeatherFilePath.filePath)) {
DisplayString(
state,
"ERROR: Could not find weather file: " + FileSystem::getAbsolutePath(state.files.inputWeatherFilePath.filePath).string() + ".");
fmt::format("ERROR: Could not find weather file: {}.", FileSystem::getAbsolutePath(state.files.inputWeatherFilePath.filePath)));
DisplayString(state, errorFollowUp);
if (eplusRunningViaAPI) {
return static_cast<int>(ReturnCodes::Failure);
Expand All @@ -561,14 +582,14 @@ state.dataStrGlobals->inputFilePath='{}',
if (runEPMacro) {
fs::path epMacroPath = (state.dataStrGlobals->exeDirectoryPath / "EPMacro").replace_extension(FileSystem::exeExtension);
if (!FileSystem::fileExists(epMacroPath)) {
DisplayString(state, "ERROR: Could not find EPMacro executable: " + FileSystem::getAbsolutePath(epMacroPath).string() + ".");
DisplayString(state, fmt::format("ERROR: Could not find EPMacro executable: {}.", FileSystem::getAbsolutePath(epMacroPath)));
if (eplusRunningViaAPI) {
return static_cast<int>(ReturnCodes::Failure);
} else {
exit(EXIT_FAILURE);
}
}
std::string epMacroCommand = "\"" + epMacroPath.string() + "\"";
std::string epMacroCommand = "\"" + FileSystem::toString(epMacroPath) + "\"";
bool inputFilePathdIn = (FileSystem::getAbsolutePath(state.dataStrGlobals->inputFilePath) == FileSystem::getAbsolutePath("in.imf"));

if (!inputFilePathdIn) {
Expand All @@ -589,21 +610,21 @@ state.dataStrGlobals->inputFilePath='{}',
(state.dataStrGlobals->exeDirectoryPath / fs::path("ExpandObjects")).replace_extension(FileSystem::exeExtension);
if (!FileSystem::fileExists(expandObjectsPath)) {
DisplayString(state,
"ERROR: Could not find ExpandObjects executable: " + FileSystem::getAbsolutePath(expandObjectsPath).string() + ".");
fmt::format("ERROR: Could not find ExpandObjects executable: {}.", FileSystem::getAbsolutePath(expandObjectsPath)));
if (eplusRunningViaAPI) {
return static_cast<int>(ReturnCodes::Failure);
} else {
exit(EXIT_FAILURE);
}
}
std::string expandObjectsCommand = "\"" + expandObjectsPath.string() + "\"";
std::string expandObjectsCommand = "\"" + FileSystem::toString(expandObjectsPath) + "\"";
bool inputFilePathdIn = (FileSystem::getAbsolutePath(state.dataStrGlobals->inputFilePath) == FileSystem::getAbsolutePath("in.idf"));

// check if IDD actually exists since ExpandObjects still requires it
if (!FileSystem::fileExists(state.dataStrGlobals->inputIddFilePath)) {
DisplayString(state,
"ERROR: Could not find input data dictionary: " +
FileSystem::getAbsolutePath(state.dataStrGlobals->inputIddFilePath).string() + ".");
fmt::format("ERROR: Could not find input data dictionary: {}.",
FileSystem::getAbsolutePath(state.dataStrGlobals->inputIddFilePath)));
DisplayString(state, errorFollowUp);
if (eplusRunningViaAPI) {
return static_cast<int>(ReturnCodes::Failure);
Expand Down Expand Up @@ -797,7 +818,7 @@ state.dataStrGlobals->inputFilePath='{}',
state,
"ERROR: Could not find ReadVarsESO executable. When calling through C API, make sure to call setEnergyPlusRootDirectory");
} else {
DisplayString(state, "ERROR: Could not find ReadVarsESO executable: " + FileSystem::getAbsolutePath(readVarsPath).string() + ".");
DisplayString(state, fmt::format("ERROR: Could not find ReadVarsESO executable: {}.", FileSystem::getAbsolutePath(readVarsPath)));
}
return static_cast<int>(ReturnCodes::Failure);
}
Expand All @@ -810,28 +831,28 @@ state.dataStrGlobals->inputFilePath='{}',
if (!rviFileExists) {
std::ofstream ofs{RVIfile};
if (!ofs.good()) {
ShowFatalError(state, format("EnergyPlus: Could not open file \"{}\" for output (write).", RVIfile.string()));
ShowFatalError(state, format("EnergyPlus: Could not open file \"{}\" for output (write).", RVIfile));
} else {
ofs << state.files.eso.filePath.string() << '\n';
ofs << state.files.csv.filePath.string() << '\n';
ofs << FileSystem::toString(state.files.eso.filePath) << '\n';
ofs << FileSystem::toString(state.files.csv.filePath) << '\n';
}
}

const bool mviFileExists = FileSystem::fileExists(MVIfile);
if (!mviFileExists) {
std::ofstream ofs{MVIfile};
if (!ofs.good()) {
ShowFatalError(state, format("EnergyPlus: Could not open file \"{}\" for output (write).", RVIfile.string()));
ShowFatalError(state, format("EnergyPlus: Could not open file \"{}\" for output (write).", RVIfile));
} else {
ofs << state.files.mtr.filePath.string() << '\n';
ofs << state.files.mtr_csv.filePath.string() << '\n';
ofs << FileSystem::toString(state.files.mtr.filePath) << '\n';
ofs << FileSystem::toString(state.files.mtr_csv.filePath) << '\n';
}
}

// We quote the paths in case we have spaces
// "/Path/to/ReadVarEso" "/Path/to/folder with spaces/file.rvi" unlimited
std::string const readVarsRviCommand = "\"" + readVarsPath.string() + "\" \"" + RVIfile.string() + "\" unlimited";
std::string const readVarsMviCommand = "\"" + readVarsPath.string() + "\" \"" + MVIfile.string() + "\" unlimited";
std::string const readVarsRviCommand = "\"" + FileSystem::toString(readVarsPath) + "\" \"" + FileSystem::toString(RVIfile) + "\" unlimited";
std::string const readVarsMviCommand = "\"" + FileSystem::toString(readVarsPath) + "\" \"" + FileSystem::toString(MVIfile) + "\" unlimited";

// systemCall will be responsible to handle to above command on Windows versus Unix
FileSystem::systemCall(readVarsRviCommand);
Expand Down
Loading

5 comments on commit 2fa11f3

@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.

10065ChillerHeaterFix (RKStrand) - x86_64-Linux-Ubuntu-22.04-gcc-11.4: OK (3695 of 3695 tests passed, 0 test warnings)

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.

10065ChillerHeaterFix (RKStrand) - x86_64-MacOS-10.18-clang-15.0.0: OK (3654 of 3654 tests passed, 0 test warnings)

Build Badge Test Badge

@nrel-bot
Copy link

Choose a reason for hiding this comment

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

10065ChillerHeaterFix (RKStrand) - Win64-Windows-10-VisualStudio-16: OK (2862 of 2862 tests passed, 0 test warnings)

Build Badge Test Badge

@nrel-bot-2c
Copy link

Choose a reason for hiding this comment

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

10065ChillerHeaterFix (RKStrand) - x86_64-Linux-Ubuntu-22.04-gcc-11.4-UnitTestsCoverage-Debug: OK (2070 of 2070 tests passed, 0 test warnings)

Build Badge Test Badge Coverage Badge

@nrel-bot-2
Copy link

Choose a reason for hiding this comment

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

10065ChillerHeaterFix (RKStrand) - x86_64-Linux-Ubuntu-22.04-gcc-11.4-IntegrationCoverage-Debug: OK (795 of 795 tests passed, 0 test warnings)

Build Badge Test Badge Coverage Badge

Please sign in to comment.