Skip to content

Commit

Permalink
moved File:Shading + Overloads for ProcessNum + Added checks
Browse files Browse the repository at this point in the history
  • Loading branch information
jmythms committed May 29, 2021
1 parent ddad276 commit f68ec73
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 68 deletions.
145 changes: 78 additions & 67 deletions src/EnergyPlus/ScheduleManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ namespace ScheduleManager {

// Functions



void ProcessScheduleInput(EnergyPlusData &state)
{

Expand Down Expand Up @@ -231,7 +233,7 @@ namespace ScheduleManager {
Array1D_bool AllDays(MaxDayTypes);
Array1D_bool TheseDays(MaxDayTypes);
bool ErrorHere;
int SchNum;
int SchNum{};
int WkCount;
int DyCount;
int NumField;
Expand Down Expand Up @@ -269,7 +271,7 @@ namespace ScheduleManager {
std::string ColumnSep;
bool firstLine;
int rowLimitCount;
int numerrors;
int numerrors{};
int ifld;
int hrLimitCount;

Expand Down Expand Up @@ -644,58 +646,6 @@ namespace ScheduleManager {
"{}\n",
" Processing Schedule Input -- Start");

std::string curName;
Array1D<Real64> timestepColumnValues;
for (auto &NameValue : CSVAllColumnNames) {
curName = NameValue.first + "_shading";
timestepColumnValues = CSVAllColumnNameAndValues[NameValue.second];
GlobalNames::VerifyUniqueInterObjectName(
state, state.dataScheduleMgr->UniqueScheduleNames, curName, CurrentModuleObject, cAlphaFields(1), ErrorsFound);
++SchNum;
state.dataScheduleMgr->Schedule(SchNum).Name = curName;
state.dataScheduleMgr->Schedule(SchNum).SchType = SchedType::ScheduleInput_file;

iDay = 0;
ifld = 0;
while (true) {
// create string of which day of year
++iDay;
if (iDay > 366) {
break;
}
ExtraField = fmt::to_string(iDay);
// increment both since a week schedule is being defined for each day so that a day is valid
// no matter what the day type that is used in a design day.
++AddWeekSch;
++AddDaySch;
// define week schedule
state.dataScheduleMgr->WeekSchedule(AddWeekSch).Name = curName + "_shading_wk_" + ExtraField;
// for all day types point the week schedule to the newly defined day schedule
for (kDayType = 1; kDayType <= MaxDayTypes; ++kDayType) {
state.dataScheduleMgr->WeekSchedule(AddWeekSch).DaySchedulePointer(kDayType) = AddDaySch;
}
// day schedule
state.dataScheduleMgr->DaySchedule(AddDaySch).Name = curName + "_shading_dy_" + ExtraField;
state.dataScheduleMgr->DaySchedule(AddDaySch).ScheduleTypePtr = state.dataScheduleMgr->Schedule(SchNum).ScheduleTypePtr;
// schedule is pointing to the week schedule
state.dataScheduleMgr->Schedule(SchNum).WeekSchedulePointer(iDay) = AddWeekSch;

for (jHour = 1; jHour <= 24; ++jHour) {
for (TS = 1; TS <= state.dataGlobal->NumOfTimeStepInHour; ++TS) {
++ifld;
curHrVal = timestepColumnValues(ifld);
state.dataScheduleMgr->DaySchedule(AddDaySch).TSValue(TS, jHour) = curHrVal;
}
}
if (iDay == 59 && !state.dataEnvrn->CurrentYearIsLeapYear) { // 28 Feb
// Dup 28 Feb to 29 Feb (60)
++iDay;
state.dataScheduleMgr->Schedule(SchNum).WeekSchedulePointer(iDay) =
state.dataScheduleMgr->Schedule(SchNum).WeekSchedulePointer(iDay - 1);
}
}
}

//!! Get Schedule Types

CurrentModuleObject = "ScheduleTypeLimits";
Expand Down Expand Up @@ -1761,51 +1711,60 @@ namespace ScheduleManager {

std::ifstream file(fileNameItem);
CSVRow row;
// TODO : Fix delimiter issue
// TODO : Fix delimiter issue: check if there are other delimiters specified, if yes, throw error
row.delimiter = state.dataScheduleMgr->columnarData[colNumToColDataIndex[vectorOfCSVColNumbers[0]]]
.delimiter; // all schedules in one file will have the same delimiter


while (file >> row)
// find which columns of this csv map to which schedule - not needed
// How to do this? Make a mapOfMaps which has for each fileName, a map of scheduleNames, ColumnNumbers

// find schedules to be filled with columns from this file
// if column is important, check if this row needs to be skipped
// Else add to the right cell
{
for (int colNum : vectorOfCSVColNumbers) {

std::string x = static_cast<std::string>(row[colNum]);
/// a
Real64 a = UtilityRoutines::ProcessNumber(x, ErrorsFound); // Overload
/// b
state.dataScheduleMgr->columnarData[colNumToColDataIndex[colNum]].vals.emplace_back(a); // row[colNum]
// skip if row needs to be skipped
if (state.dataScheduleMgr->columnarData[colNumToColDataIndex[colNum]].rowsToSkip){
--state.dataScheduleMgr->columnarData[colNumToColDataIndex[colNum]].rowsToSkip;
continue;
} // TODO : Add check if the number of rows skipped were correct (What if the user input was wrong?)

columnValue = UtilityRoutines::ProcessNumber(row[colNum], errFlag);
if (errFlag) {
++++state.dataScheduleMgr->columnarData[colNumToColDataIndex[colNum]].numerrors;
columnValue = 0.0;
}

state.dataScheduleMgr->columnarData[colNumToColDataIndex[colNum]].vals.emplace_back(columnValue); // row[colNum]
++state.dataScheduleMgr->columnarData[colNumToColDataIndex[colNum]].rowCnt;

// TODO : if there are multiple common elements in vectorOfCSVColNumbers, there is an error.
}
}
}


// schedule values have been filled into the columnarData.vals vectors.

// skip rows when needed
// skip rows when needed - potentially unnecessary, since
for (auto &schedule : state.dataScheduleMgr->columnarData) {
if (schedule.rowsToSkip != -1) {
schedule.vals.erase(schedule.vals.begin(), schedule.vals.begin() + schedule.rowsToSkip);
}
}

for (const PreProcessedColumn &schedule : state.dataScheduleMgr->columnarData) {
if (numerrors > 0) {
rowLimitCount = (schedule.numHourlyValues * 60) / schedule.MinutesPerItem;
if (schedule.numerrors > 0) {
ShowWarningError(state,
format("{}{}=\"{}\" {} records had errors - these values are set to 0.",
RoutineName,
CurrentModuleObject,
schedule.name,
numerrors));
schedule.numerrors));
ShowContinueError(state, "Use Output:Diagnostics,DisplayExtraWarnings; to see individual records in error.");
}
if (rowCnt < rowLimitCount) {
if (schedule.rowCnt < rowLimitCount) {
ShowWarningError(state,
format("{}{}=\"{}\" less than {} hourly values read from file.",
RoutineName,
Expand Down Expand Up @@ -1911,6 +1870,58 @@ namespace ScheduleManager {
hourlyFileValues.deallocate();
}

std::string curName;
Array1D<Real64> timestepColumnValues;
for (auto &NameValue : CSVAllColumnNames) {
curName = NameValue.first + "_shading";
timestepColumnValues = CSVAllColumnNameAndValues[NameValue.second];
GlobalNames::VerifyUniqueInterObjectName(
state, state.dataScheduleMgr->UniqueScheduleNames, curName, CurrentModuleObject, cAlphaFields(1), ErrorsFound);
++SchNum;
state.dataScheduleMgr->Schedule(SchNum).Name = curName;
state.dataScheduleMgr->Schedule(SchNum).SchType = SchedType::ScheduleInput_file;

iDay = 0;
ifld = 0;
while (true) {
// create string of which day of year
++iDay;
if (iDay > 366) {
break;
}
ExtraField = fmt::to_string(iDay);
// increment both since a week schedule is being defined for each day so that a day is valid
// no matter what the day type that is used in a design day.
++AddWeekSch;
++AddDaySch;
// define week schedule
state.dataScheduleMgr->WeekSchedule(AddWeekSch).Name = curName + "_shading_wk_" + ExtraField;
// for all day types point the week schedule to the newly defined day schedule
for (kDayType = 1; kDayType <= MaxDayTypes; ++kDayType) {
state.dataScheduleMgr->WeekSchedule(AddWeekSch).DaySchedulePointer(kDayType) = AddDaySch;
}
// day schedule
state.dataScheduleMgr->DaySchedule(AddDaySch).Name = curName + "_shading_dy_" + ExtraField;
state.dataScheduleMgr->DaySchedule(AddDaySch).ScheduleTypePtr = state.dataScheduleMgr->Schedule(SchNum).ScheduleTypePtr;
// schedule is pointing to the week schedule
state.dataScheduleMgr->Schedule(SchNum).WeekSchedulePointer(iDay) = AddWeekSch;

for (jHour = 1; jHour <= 24; ++jHour) {
for (TS = 1; TS <= state.dataGlobal->NumOfTimeStepInHour; ++TS) {
++ifld;
curHrVal = timestepColumnValues(ifld);
state.dataScheduleMgr->DaySchedule(AddDaySch).TSValue(TS, jHour) = curHrVal;
}
}
if (iDay == 59 && !state.dataEnvrn->CurrentYearIsLeapYear) { // 28 Feb
// Dup 28 Feb to 29 Feb (60)
++iDay;
state.dataScheduleMgr->Schedule(SchNum).WeekSchedulePointer(iDay) =
state.dataScheduleMgr->Schedule(SchNum).WeekSchedulePointer(iDay - 1);
}
}
}

MinuteValue.deallocate();
SetMinuteValue.deallocate();

Expand Down
2 changes: 2 additions & 0 deletions src/EnergyPlus/ScheduleManager.hh
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,8 @@ namespace ScheduleManager {
bool FileIntervalInterpolated = false;
int ScheduleTypePtr = -1;
int SchNum = -1;
int rowCnt = 0;
int numerrors = 0;
std::string fileName;
std::string delimiter;
std::vector<Real64> vals; // rows to skip + number of hours*items/hour
Expand Down
23 changes: 23 additions & 0 deletions src/EnergyPlus/StringUtilities.hh
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ inline std::stringstream stringReader(std::string str)
return result;
}

inline std::stringstream stringReader(std::string_view str)
{
std::stringstream ss;
ss << str;
ss.imbue(std::locale("C")); // the forced locale is to avoid issues with parsing floating point numbers that use non-decimal formats
return ss;
}

template <typename Param> bool readListItem(std::istream &stream, Param &&param)
{
if (stream.good()) {
Expand All @@ -80,6 +88,21 @@ template <typename Param> bool readItem(std::string input, Param &&param)
{
auto stream = stringReader(std::move(input));
stream >> param;

return !stream.fail() && stream.eof();
}

template <typename Param> bool readItem(std::string_view input, Param &&param)
{
std::string temp_string = static_cast<std::string>(stripped(input));
// make FORTRAN floating point number (containing 'd' or 'D')
// standardized by replacing 'd' or 'D' with 'e'
std::replace_if(
std::begin(temp_string), std::end(temp_string), [](const char c) { return c == 'D' || c == 'd'; }, 'e');
auto stream = stringReader(temp_string);

stream >> param;

return !stream.fail() && stream.eof();
}

Expand Down
57 changes: 56 additions & 1 deletion src/EnergyPlus/UtilityRoutines.cc
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ namespace UtilityRoutines {
// List directed Fortran input/output.

// SUBROUTINE PARAMETER DEFINITIONS:
static std::string const ValidNumerics("0123456789.+-EeDd");
static constexpr std::string_view ValidNumerics("0123456789.+-EeDd");

Real64 rProcessNumber = 0.0;
// Make sure the string has all what we think numerics should have
Expand Down Expand Up @@ -151,6 +151,61 @@ namespace UtilityRoutines {
return rProcessNumber;
}

Real64 ProcessNumber(std::basic_string_view<char> const &String_view, bool &ErrorFlag)
{

// FUNCTION INFORMATION:
// AUTHOR Linda K. Lawrie
// DATE WRITTEN September 1997
// MODIFIED na
// RE-ENGINEERED na

// PURPOSE OF THIS FUNCTION:
// This function processes a string that should be numeric and
// returns the real value of the string.

// METHODOLOGY EMPLOYED:
// FUNCTION ProcessNumber translates the argument (a string)
// into a real number. The string should consist of all
// numeric characters (except a decimal point). Numerics
// with exponentiation (i.e. 1.2345E+03) are allowed but if
// it is not a valid number an error message along with the
// string causing the error is printed out and 0.0 is returned
// as the value.

// REFERENCES:
// List directed Fortran input/output.

// SUBROUTINE PARAMETER DEFINITIONS:
static constexpr std::string_view ValidNumerics("0123456789.+-EeDd");

Real64 rProcessNumber = 0.0;
// Make sure the string has all what we think numerics should have
std::string_view PString((String_view)); // stripped - > moved to readItem
std::string::size_type const StringLen(PString.length());
ErrorFlag = false;
if (StringLen == 0) return rProcessNumber;
bool parseFailed = false;
if (PString.find_first_not_of(ValidNumerics) == std::string::npos) {

// std::replace_if - > moved to readItem
// is this not working because string_view is acting like a const variable? // Do we need to convert/cast it here? -> move this to the 'deepest' function so that the copying can be minimized

// then parse as a normal floating point value
parseFailed = !readItem(PString, rProcessNumber);
ErrorFlag = false;
} else {
rProcessNumber = 0.0;
ErrorFlag = true;
}
if (parseFailed) {
rProcessNumber = 0.0;
ErrorFlag = true;
}

return rProcessNumber;
}

int FindItemInList(std::string const &String, Array1_string const &ListOfItems, int const NumItems)
{

Expand Down
1 change: 1 addition & 0 deletions src/EnergyPlus/UtilityRoutines.hh
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ namespace UtilityRoutines {
};

Real64 ProcessNumber(std::string const &String, bool &ErrorFlag);
Real64 ProcessNumber(std::basic_string_view<char> const &String_view, bool &ErrorFlag);

int FindItemInList(std::string const &String, Array1_string const &ListOfItems, int NumItems);

Expand Down
16 changes: 16 additions & 0 deletions third_party/ObjexxFCL/src/ObjexxFCL/string.functions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,22 @@ stripped( std::string const & s )
}
}

std::string_view
stripped( std::string_view const & s )
{
if ( s.empty() ) {
return s;
} else {
std::string::size_type const ib( s.find_first_not_of( ' ' ) );
std::string::size_type const ie( s.find_last_not_of( ' ' ) );
if ( ( ib == std::string::npos ) || ( ie == std::string::npos ) ) { // All of string is ' '
return std::string(); // Return empty string
} else {
return s.substr( ib, ie - ib + 1 );
}
}
}

// Space Stripped from a string's Left Tail Copy of a string
std::string
lstripped( std::string const & s )
Expand Down
3 changes: 3 additions & 0 deletions third_party/ObjexxFCL/src/ObjexxFCL/string.functions.hh
Original file line number Diff line number Diff line change
Expand Up @@ -1557,6 +1557,9 @@ rstripped( std::string const & s, std::string const & chars );
std::string
stripped( std::string const & s );

std::string_view
stripped( std::string_view const & s );

// Space Stripped from a string's Left Tail Copy of a string
std::string
lstripped( std::string const & s );
Expand Down

5 comments on commit f68ec73

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

schedManGoZoom (jmythms) - x86_64-Linux-Ubuntu-18.04-gcc-7.5-UnitTestsCoverage-Debug: Build Failed

Build Badge Test Badge Coverage 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.

schedManGoZoom (jmythms) - x86_64-MacOS-10.15-clang-11.0.0: Build Failed

Messages:\n

  • 674 tests had: RDD diffs.
  • 2 tests 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.

schedManGoZoom (jmythms) - x86_64-Linux-Ubuntu-18.04-gcc-7.5: Build Failed

Messages:\n

  • 678 tests had: RDD diffs.
  • 2 tests had: ERR diffs.
  • 1 test had: EIO diffs.
  • 1 test had: ESO small diffs.
  • 1 test had: MTR small diffs.
  • 1 test had: Table big diffs.

Failures:\n

regression Test Summary

  • Passed: 741
  • Failed: 1

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.

schedManGoZoom (jmythms) - Win64-Windows-10-VisualStudio-16: Build Failed

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.

schedManGoZoom (jmythms) - x86_64-Linux-Ubuntu-18.04-gcc-7.5-IntegrationCoverage-Debug: Build Failed

Build Badge Test Badge Coverage Badge

Please sign in to comment.