From f21e5886cfb7cf1d9b71eda5834c3b27a98622bf Mon Sep 17 00:00:00 2001 From: Phil Ahrenkiel Date: Wed, 20 Dec 2023 12:09:18 -0700 Subject: [PATCH] Improve calcUEF and test options. --- src/HPWH.cc | 98 +++++++++++++++++++++++------------------- src/HPWH.hh | 3 +- test/AquaThermAire.txt | 1 - test/main.cc | 39 ++++++++++------- test/testCalcUEF.cc | 54 ++++++++++++----------- 5 files changed, 108 insertions(+), 87 deletions(-) diff --git a/src/HPWH.cc b/src/HPWH.cc index 720c0401..d6484ef1 100644 --- a/src/HPWH.cc +++ b/src/HPWH.cc @@ -314,7 +314,6 @@ void HPWH::setAllDefaults() { prevDRstatus = DR_ALLOW; timerLimitTOT = 60.; timerTOT = 0.; usesSoCLogic = false; setMinutesPerStep(1.0); - hpwhVerbosity = VRB_minuteOut; hasHeatExchanger = false; heatExchangerEffectiveness = 0.9; } @@ -4116,7 +4115,8 @@ bool HPWH::readControlInfo(const std::string &testDirectory, HPWH::ControlInfo & controlInfo.tot_limit = nullptr; controlInfo.useSoC = false; controlInfo.temperatureUnits = "C"; - controlInfo.extendedTest = false; + controlInfo.recordMinuteData = false; + controlInfo.recordYearData = false; std::string token; std::string sValue; @@ -4294,33 +4294,37 @@ bool HPWH::runSimulation( // UEF data testResults = {false, 0., 0.}; - FILE * outputFile = NULL; - std::string sOutputFilename; - std::string fileMode = "w+"; - if (controlInfo.extendedTest) { - sOutputFilename = outputDirectory + "/DHW_YRLY.csv"; - fileMode = "a+"; - } - else { - sOutputFilename = outputDirectory + "/" + testDesc.testName + "_" + testDesc.presetOrFile + "_" + testDesc.modelName + ".csv"; + FILE *yearOutputFile = NULL; + if (controlInfo.recordYearData) { + std::string sOutputFilename = outputDirectory + "/DHW_YRLY.csv"; + if (fopen_s(&yearOutputFile, sOutputFilename.c_str(), "a+") != 0) { + if(hpwhVerbosity >= VRB_reluctant) { + msg("Could not open output file \n", sOutputFilename.c_str()); + } + return false; + } } - if (fopen_s(&outputFile, sOutputFilename.c_str(), fileMode.c_str()) != 0) { - if(hpwhVerbosity >= VRB_reluctant) { - msg("Could not open output file \n", sOutputFilename.c_str()); + FILE *minuteOutputFile = NULL; + if (controlInfo.recordMinuteData) { + std::string sOutputFilename = outputDirectory + "/" + testDesc.testName + "_" + testDesc.presetOrFile + "_" + testDesc.modelName + ".csv"; + if (fopen_s(&minuteOutputFile, sOutputFilename.c_str(), "w+") != 0) { + if(hpwhVerbosity >= VRB_reluctant) { + msg("Could not open output file \n", sOutputFilename.c_str()); + } + return false; } - return false; - } + } - string sHeader = "minutes,Ta,Tsetpoint,inletT,draw,"; - if (!controlInfo.extendedTest) { + if (controlInfo.recordMinuteData) { + string sHeader = "minutes,Ta,Tsetpoint,inletT,draw,"; if (isCompressoExternalMultipass()) { sHeader += "condenserInletT,condenserOutletT,externalVolGPM,"; } if(controlInfo.useSoC){ sHeader += "targetSoCFract,soCFract,"; } - WriteCSVHeading(outputFile, sHeader.c_str(), nTestTCouples, CSVOPT_NONE); + WriteCSVHeading(minuteOutputFile, sHeader.c_str(), nTestTCouples, CSVOPT_NONE); } // ------------------------------------- Simulate --------------------------------------- // @@ -4328,8 +4332,8 @@ bool HPWH::runSimulation( msg("Now Simulating %d Minutes of the Test\n", controlInfo.timeToRun_min); } - double cumHeatIn[3] = {0, 0, 0}; - double cumHeatOut[3] = {0, 0, 0}; + double cumulativeEnergyIn_kWh[3] = {0., 0., 0.}; + double cumulativeEnergyOut_kWh[3] = {0., 0., 0.}; bool doChangeSetpoint = (!allSchedules[5].empty()) && (!isSetpointFixed()); @@ -4357,9 +4361,9 @@ bool HPWH::runSimulation( } } - if (controlInfo.extendedTest) { + if (controlInfo.recordYearData) { // Mix down for yearly tests with large compressors - if (getHPWHModel() >= 210) { + if (getHPWHModel() >= MODELS_ColmacCxV_5_SP) { //Do a simple mix down of the draw for the cold water temperature const double mixT_C = F_TO_C(125.); if (getSetpoint() <= mixT_C) { // Seems to have been some confusion here regarding F<->C conversion @@ -4427,7 +4431,8 @@ bool HPWH::runSimulation( ambientT_C = getLocationTemp_C(); } - if (!controlInfo.extendedTest) { + // write minute summary + if (controlInfo.recordMinuteData) { std::string sPreamble = std::to_string(i) + ", " + std::to_string(ambientT_C) + ", " + std::to_string(getSetpoint()) + ", " + std::to_string(allSchedules[0][i]) + ", " + std::to_string(allSchedules[1][i]) + ", "; // Add some more outputs for mp tests @@ -4442,41 +4447,46 @@ bool HPWH::runSimulation( if (allSchedules[1][i] > 0.) { csvOptions |= CSVOPT_IS_DRAWING; } - WriteCSVRow(outputFile, sPreamble.c_str(), nTestTCouples, csvOptions); + WriteCSVRow(minuteOutputFile, sPreamble.c_str(), nTestTCouples, csvOptions); } - // track energy draw and use - double energyConsumed_kJ = 0.; + // accumulate energy and draw + double energyIn_kJ = 0.; for (int iHS = 0; iHS < getNumHeatSources(); iHS++) { - double heatSourceEnergyConsumed_kJ = getNthHeatSourceEnergyInput(iHS, HPWH::UNITS_KJ); - energyConsumed_kJ += heatSourceEnergyConsumed_kJ; + double heatSourceEnergyIn_kJ = getNthHeatSourceEnergyInput(iHS, HPWH::UNITS_KJ); + energyIn_kJ += heatSourceEnergyIn_kJ; - cumHeatIn[iHS] += KJ_TO_KWH(heatSourceEnergyConsumed_kJ) * 1000.; - cumHeatOut[iHS] += getNthHeatSourceEnergyOutput(iHS, HPWH::UNITS_KWH) * 1000.; + cumulativeEnergyIn_kWh[iHS] += KJ_TO_KWH(heatSourceEnergyIn_kJ) * 1000.; + cumulativeEnergyOut_kWh[iHS] += getNthHeatSourceEnergyOutput(iHS, HPWH::UNITS_KWH) * 1000.; } - testResults.totalEnergyConsumed_kJ += energyConsumed_kJ; + testResults.totalEnergyConsumed_kJ += energyIn_kJ; testResults.totalVolumeRemoved_L += drawVolume_L; } + // -------------------------------------Simulation complete --------------------------------------- // - if (controlInfo.extendedTest) { + if (controlInfo.recordMinuteData) { + fclose(minuteOutputFile); + } + + // write year summary + if (controlInfo.recordYearData) { std::string firstCol = testDesc.testName + "," + testDesc.presetOrFile + "," + testDesc.modelName; - fprintf(outputFile, "%s", firstCol.c_str()); - double totalIn = 0, totalOut = 0; + fprintf(yearOutputFile, "%s", firstCol.c_str()); + double totalEnergyIn_kWh = 0, totalEnergyOut_kWh = 0; for (int iHS = 0; iHS < 3; iHS++) { - fprintf(outputFile, ",%0.0f,%0.0f", cumHeatIn[iHS], cumHeatOut[iHS]); - totalIn += cumHeatIn[iHS]; - totalOut += cumHeatOut[iHS]; + fprintf(yearOutputFile, ",%0.0f,%0.0f", cumulativeEnergyIn_kWh[iHS], cumulativeEnergyOut_kWh[iHS]); + totalEnergyIn_kWh += cumulativeEnergyIn_kWh[iHS]; + totalEnergyOut_kWh += cumulativeEnergyOut_kWh[iHS]; } - fprintf(outputFile, ",%0.0f,%0.0f", totalIn, totalOut); + fprintf(yearOutputFile, ",%0.0f,%0.0f", totalEnergyIn_kWh, totalEnergyOut_kWh); for (int iHS = 0; iHS < 3; iHS++) { - fprintf(outputFile, ",%0.2f", cumHeatOut[iHS] /cumHeatIn[iHS]); + fprintf(yearOutputFile, ",%0.2f", cumulativeEnergyOut_kWh[iHS] /cumulativeEnergyIn_kWh[iHS]); } - fprintf(outputFile, ",%0.2f", totalOut/totalIn); - fprintf(outputFile, "\n"); + fprintf(yearOutputFile, ",%0.2f", totalEnergyOut_kWh/totalEnergyIn_kWh); + fprintf(yearOutputFile, "\n"); + fclose(yearOutputFile); } - fclose(outputFile); - testResults.passed = true; return true; } diff --git a/src/HPWH.hh b/src/HPWH.hh index e8acb6dd..c0acd306 100644 --- a/src/HPWH.hh +++ b/src/HPWH.hh @@ -831,7 +831,8 @@ public: std::unique_ptr tot_limit; bool useSoC; std::string temperatureUnits; - bool extendedTest; + bool recordMinuteData; + bool recordYearData; }; bool readControlInfo(const std::string &testDirectory, ControlInfo &controlInfo); diff --git a/test/AquaThermAire.txt b/test/AquaThermAire.txt index 04f47fa4..a53730a3 100644 --- a/test/AquaThermAire.txt +++ b/test/AquaThermAire.txt @@ -1,4 +1,3 @@ -verbosity silent numNodes 12 #number of nodes setpoint 50 C volume 54.4 gal diff --git a/test/main.cc b/test/main.cc index b9197d67..d9a0f775 100644 --- a/test/main.cc +++ b/test/main.cc @@ -25,21 +25,23 @@ using std::ifstream; int main(int argc, char *argv[]){ HPWH hpwh; - bool failed = false; const long maximumDurationNormalTest_min = 500000; +#if defined _DEBUG + hpwh.setVerbosity(HPWH::VRB_reluctant); +#endif + // process command line arguments cout << "Testing HPWHsim version " << HPWH::getVersion() << endl; // Obvious wrong number of command line arguments if ((argc > 6)) { cout << "Invalid input. This program takes FOUR arguments: model specification type (ie. Preset or File), model specification (ie. Sanden80), test name (ie. test50) and output directory\n"; - failed = true; + exit(1); } - ASSERTFALSE(failed); - // Help message + // parse inputs std::string input1, input2, input3, input4; if(argc > 1) { input1 = argv[1]; @@ -52,14 +54,15 @@ int main(int argc, char *argv[]){ input3 = "ghi"; input4 = "."; } + + // display help message if (argc < 5 || (argc > 6) || (input1 == "?") || (input1 == "help")) { cout << "Standard usage: \"hpwhTestTool.x [model spec type Preset/File] [model spec Name] [testName] [airtemp override F (optional)]\"\n"; cout << "All input files should be located in the test directory, with these names:\n"; cout << "drawschedule.csv DRschedule.csv ambientTschedule.csv evaporatorTschedule.csv inletTschedule.csv hpwhProperties.csv\n"; cout << "An output file, `modelname'Output.csv, will be written in the test directory\n"; - failed = true; + exit(1); } - ASSERTFALSE(failed); HPWH::TestDesc testDesc; testDesc.presetOrFile = input1; @@ -71,17 +74,18 @@ int main(int argc, char *argv[]){ if(testDesc.presetOrFile == "Preset") { if (getHPWHObject(hpwh, testDesc.modelName) == HPWH::HPWH_ABORT) { cout << "Error, preset model did not initialize.\n"; - failed = true; + exit(1); } } else if (testDesc.presetOrFile == "File") { std::string inputFile = testDesc.modelName + ".txt"; - if (hpwh.HPWHinit_file(inputFile) != 0) exit(1); + if (hpwh.HPWHinit_file(inputFile) != 0) { + exit(1); + } } else { cout << "Invalid argument, received '"<< testDesc.presetOrFile << "', expected 'Preset' or 'File'.\n"; - failed = true; + exit(1); } - ASSERTFALSE(failed); double airT_C = 0.; bool doTempDepress = false; @@ -98,18 +102,21 @@ int main(int argc, char *argv[]){ HPWH::ControlInfo controlInfo; if(!hpwh.readControlInfo(testDesc.testName,controlInfo)){ cout << "Control file testInfo.txt has unsettable specifics in it. \n"; - failed = true; + exit(1); } - ASSERTFALSE(failed); std::vector allSchedules; - failed = !hpwh.readSchedules(testDesc.testName,controlInfo,allSchedules); - ASSERTFALSE(failed); + if (!hpwh.readSchedules(testDesc.testName,controlInfo,allSchedules)) { + exit(1); + } - controlInfo.extendedTest = (controlInfo.timeToRun_min > maximumDurationNormalTest_min); + controlInfo.recordMinuteData = (controlInfo.timeToRun_min <= maximumDurationNormalTest_min); + controlInfo.recordYearData = !controlInfo.recordMinuteData; HPWH::TestResults testResults; - ASSERTTRUE(hpwh.runSimulation(testDesc,outputDirectory,controlInfo,allSchedules,airT_C,doTempDepress,testResults)); + if (!hpwh.runSimulation(testDesc,outputDirectory,controlInfo,allSchedules,airT_C,doTempDepress,testResults)) { + exit(1); + } return 0; } diff --git a/test/testCalcUEF.cc b/test/testCalcUEF.cc index d540e392..1c07dc69 100644 --- a/test/testCalcUEF.cc +++ b/test/testCalcUEF.cc @@ -12,7 +12,7 @@ const std::vector sProfileNames({ "24hr67_vsmall", "24hr67_medium", "24hr67_high" }); -bool runTest( +static bool runTest( const HPWH::TestDesc testDesc, HPWH::TestResults &testResults, double airT_C = 0., @@ -20,24 +20,23 @@ bool runTest( { HPWH hpwh; +#if defined _DEBUG + hpwh.setVerbosity(HPWH::VRB_reluctant); +#endif + getHPWHObject(hpwh, testDesc.modelName); std::string sOutputDirectory = "../build/test/output"; - // Parse the model + // create the model + bool result = true; if(testDesc.presetOrFile == "Preset") { - if (getHPWHObject(hpwh, testDesc.modelName) == HPWH::HPWH_ABORT) { - cout << "Error, preset model did not initialize.\n"; - exit(1); - } + result = (getHPWHObject(hpwh, testDesc.modelName) != HPWH::HPWH_ABORT); } else if (testDesc.presetOrFile == "File") { std::string inputFile = testDesc.modelName + ".txt"; - if (hpwh.HPWHinit_file(inputFile) != 0) exit(1); - } - else { - cout << "Invalid argument, received '"<< testDesc.presetOrFile << "', expected 'Preset' or 'File'.\n"; - exit(1); + result = (hpwh.HPWHinit_file(inputFile) != HPWH::HPWH_ABORT); } + ASSERTTRUE(result); // Use the built-in temperature depression for the lockout test. Set the temp depression of 4C to better // try and trigger the lockout and hysteresis conditions @@ -45,22 +44,23 @@ bool runTest( hpwh.setDoTempDepression(doTempDepress); HPWH::ControlInfo controlInfo; - if(!hpwh.readControlInfo(testDesc.testName,controlInfo)){ - cout << "Control file testInfo.txt has unsettable specifics in it. \n"; - exit(1); - } + result = hpwh.readControlInfo(testDesc.testName,controlInfo); + ASSERTTRUE(result); std::vector allSchedules; - if (!(hpwh.readSchedules(testDesc.testName,controlInfo,allSchedules))) { - exit(1); - } + result = hpwh.readSchedules(testDesc.testName,controlInfo,allSchedules); + ASSERTTRUE(result); - return hpwh.runSimulation(testDesc,sOutputDirectory,controlInfo,allSchedules,airT_C,doTempDepress,testResults); + controlInfo.recordMinuteData = false; + controlInfo.recordYearData = false; + result = hpwh.runSimulation(testDesc,sOutputDirectory,controlInfo,allSchedules,airT_C,doTempDepress,testResults); + ASSERTTRUE(result); + return result; } -/* Test energy balance for storage tank with extra heat (solar)*/ -void runTestSuite(const std::string &sModelName,const std::string &sPresetOrFile) { +/* Evaluate UEF based on simulations using standard profiles */ +static bool runUEFTestSuite(const std::string &sModelName,const std::string &sPresetOrFile, double &UEF) { HPWH::TestDesc testDesc; testDesc.modelName = sModelName; @@ -69,10 +69,11 @@ void runTestSuite(const std::string &sModelName,const std::string &sPresetOrFile double totalEnergyConsumed_kJ = 0.; double totalVolumeRemoved_L = 0.; + bool result = true; for (auto &sProfileName: sProfileNames) { HPWH::TestResults testResults; testDesc.testName = sProfileName; - ASSERTTRUE(runTest(testDesc,testResults)); + result &= runTest(testDesc,testResults); totalEnergyConsumed_kJ += testResults.totalEnergyConsumed_kJ; totalVolumeRemoved_L += testResults.totalVolumeRemoved_L; @@ -81,8 +82,8 @@ void runTestSuite(const std::string &sModelName,const std::string &sPresetOrFile double totalHeatCapacity_kJperC = HPWH::CPWATER_kJperkgC * totalMassRemoved_kg; double refEnergy_kJ = totalHeatCapacity_kJperC * (51.7 - 14.4); - double UEF = refEnergy_kJ / totalEnergyConsumed_kJ; - std::cout << "UEF: " << UEF << "\n"; + UEF = refEnergy_kJ / totalEnergyConsumed_kJ; + return result; } int main(int argc, char *argv[]) @@ -96,7 +97,10 @@ int main(int argc, char *argv[]) std::string sPresetOrFile = argv[1]; std::string sModelName = argv[2]; - runTestSuite(sModelName,sPresetOrFile); + double UEF = 0.; + if (runUEFTestSuite(sModelName, sPresetOrFile, UEF)) { + std::cout << "UEF: " << UEF << "\n"; + } return 0; }