void saveAccumRainfall(Project* project, DateTime date1, int hour, int minute, long v) // // Input: date1 = date of latest rainfall reading (in DateTime format) // hour = hour of day of latest rain reading // minute = minute of hour of latest rain reading // v = accumulated rainfall reading in hundreths of inches // Output: none // Purpose: divides accumulated rainfall evenly into individual recording // periods over the accumulation period and writes each period's // rainfall to the binary rainfall file. // { DateTime date2; int n, j; float x; // --- return if accumulated start date is missing if ( project->AccumStartDate == NO_DATE ) return; // --- find number of recording intervals over accumulation period date2 = date1 + datetime_encodeTime(hour, minute, 0); n = (datetime_timeDiff(date2, project->AccumStartDate) / project->Interval) + 1; // --- update count of rain or missing periods if ( v == 99999 ) { project->RainStats.periodsMissing += n; return; } project->RainStats.periodsRain += n; // --- divide accumulated amount evenly into each period x = (float)v / (float)n / 100.0f; // --- save this amount to file for each period if ( x > 0.0f ) { date2 = datetime_addSeconds(project->AccumStartDate, -project->TimeOffset); if ( project->RainStats.startDate == NO_DATE ) project->RainStats.startDate = date2; for (j = 0; j < n; j++) { fwrite(&date2, sizeof(DateTime), 1, project->Frain.file); fwrite(&x, sizeof(float), 1, project->Frain.file); date2 = datetime_addSeconds(date2, project->Interval); project->RainStats.endDate = date2; } } // --- reset start of accumulation period project->AccumStartDate = NO_DATE; }
void saveRainfall(Project* project, DateTime date1, int hour, int minute, float x, char isMissing) // // Input: date1 = date of rainfall reading (in DateTime format) // hour = hour of day of current rain reading // minute = minute of hour of current rain reading // x = rainfall reading in inches // isMissing = TRUE if rainfall value is missing // Output: none // Purpose: writes current rainfall reading from an external rainfall file // to project's binary rainfall file. // { DateTime date2; double seconds; if ( isMissing ) project->RainStats.periodsMissing++; else project->RainStats.periodsRain++; // --- if rainfall not missing then save it to rainfall interface file if ( !isMissing ) { seconds = 3600*hour + 60*minute - project->TimeOffset; date2 = datetime_addSeconds(date1, seconds); // --- write date & value (in inches) to interface file fwrite(&date2, sizeof(DateTime), 1, project->Frain.file); fwrite(&x, sizeof(float), 1, project->Frain.file); // --- update actual start & end of record dates if ( project->RainStats.startDate == NO_DATE ) project->RainStats.startDate = date2; project->RainStats.endDate = date2; } }
void readRdiiFlows() // // Input: none // Output: none // Purpose: reads date and flow values of next RDII inflows from RDII file. // { int i, n; int yr = 0, mon = 0, day = 0, hr = 0, min = 0, sec = 0; // year, month, day, hour, minute, second float x; // RDII flow in original units char line[MAXLINE+1]; // line from RDII data file char s[MAXLINE+1]; // node ID label (not used) RdiiStartDate = NO_DATE; for (i=0; i<NumRdiiNodes; i++) { if ( feof(Frdii.file) ) return; fgets(line, MAXLINE, Frdii.file); n = sscanf(line, "%s %d %d %d %d %d %d %f", s, &yr, &mon, &day, &hr, &min, &sec, &x); if ( n < 8 ) return; RdiiNodeFlow[i] = x / Qcf[RdiiFlowUnits]; } RdiiStartDate = datetime_encodeDate(yr, mon, day) + datetime_encodeTime(hr, min, sec); RdiiEndDate = datetime_addSeconds(RdiiStartDate, RdiiStep); }
void gage_initState(int j) // // Input: j = rain gage index // Output: none // Purpose: initializes state of rain gage. // { // --- assume gage not used by any subcatchment // (will be updated in subcatch_initState) Gage[j].isUsed = FALSE; Gage[j].rainfall = 0.0; Gage[j].reportRainfall = 0.0; if ( IgnoreRainfall ) return; // --- for gage with file data: if ( Gage[j].dataSource == RAIN_FILE ) { // --- set current file position to start of period of record Gage[j].currentFilePos = Gage[j].startFilePos; // --- assign units conversion factor // (rain depths on interface file are in inches) if ( UnitSystem == SI ) Gage[j].unitsFactor = MMperINCH; } // --- get first & next rainfall values if ( getFirstRainfall(j) ) { // --- find date at end of starting rain interval Gage[j].endDate = datetime_addSeconds( Gage[j].startDate, Gage[j].rainInterval); // --- if rainfall record begins after start of simulation, if ( Gage[j].startDate > StartDateTime ) { // --- make next rainfall date the start of the rain record Gage[j].nextDate = Gage[j].startDate; Gage[j].nextRainfall = Gage[j].rainfall; // --- make start of current rain interval the simulation start Gage[j].startDate = StartDateTime; Gage[j].endDate = Gage[j].nextDate; Gage[j].rainfall = 0.0; } // --- otherwise find next recorded rainfall else if ( !getNextRainfall(j) ) Gage[j].nextDate = NO_DATE; } else Gage[j].startDate = NO_DATE; }
void getRainfall(DateTime currentDate) // // Input: currentDate = current calendar date/time // Output: none // Purpose: determines rainfall at current RDII processing date. // // { int j; // rain gage index int i; // past rainfall index int month; // month of current date int gageInterval; // gage recording interval (sec) float rainfall; // rainfall volume (inches or mm) DateTime gageDate; // calendar date for rain gage // --- examine each rain gage for (j = 0; j < Nobjects[GAGE]; j++) { // --- repeat until gage's date reaches or exceeds current date if ( Gage[j].isUsed == FALSE ) continue; while ( GageData[j].gageDate < currentDate ) { // --- get rainfall volume over gage's recording interval // at gage'a current date (in original depth units) gageDate = GageData[j].gageDate; gageInterval = Gage[j].rainInterval; gage_setState(j, gageDate); rainfall = Gage[j].rainfall * (float)gageInterval / 3600.0; // --- if rainfall occurs if ( rainfall > 0.0 ) { // --- if previous dry period long enough then begin // new RDII event with time period index set to 0 ////////////////////////////////////////////////////////////////////////////// // New RDII event occurs when dry period > base of longest UH. (LR - 9/19/06) ////////////////////////////////////////////////////////////////////////////// //if ( GageData[j].drySeconds >= RDII_MIT ) if ( GageData[j].drySeconds >= gageInterval * GageData[j].maxPeriods ) { for (i=0; i<GageData[j].maxPeriods; i++) { GageData[j].pastRain[i] = 0.0; } GageData[j].period = 0; } GageData[j].drySeconds = 0; GageData[j].hasPastRain = TRUE; // --- update count of total rainfall volume (ft3) TotalRainVol += rainfall / UCF(RAINDEPTH) * GageData[j].area; } // --- if no rainfall, update duration of dry period else { GageData[j].drySeconds += gageInterval; if ( GageData[j].drySeconds >= gageInterval * GageData[j].maxPeriods ) { GageData[j].hasPastRain = FALSE; } ////////////////////////// //// Added (LR - 9/19/06) ////////////////////////// else GageData[j].hasPastRain = TRUE; } // --- add rainfall to list of past values, wrapping // array index if necessary if ( GageData[j].period < GageData[j].maxPeriods ) { i = GageData[j].period; } else i = 0; GageData[j].pastRain[i] = rainfall; month = datetime_monthOfYear(currentDate) - 1; GageData[j].pastMonth[i] = (char)month; GageData[j].period = i + 1; // --- advance rain gage's date by gage recording interval GageData[j].gageDate = datetime_addSeconds(gageDate, gageInterval); } } }
void gage_setState(int j, DateTime t) // // Input: j = rain gage index // t = a calendar date/time // Output: none // Purpose: updates state of rain gage for specified date. // { // --- return if gage not used by any subcatchment if ( Gage[j].isUsed == FALSE ) return; // --- set rainfall to zero if disabled if ( IgnoreRainfall ) { Gage[j].rainfall = 0.0; return; } // --- use rainfall from co-gage (gage with lower index that uses // same rainfall time series or file) if it exists if ( Gage[j].coGage >= 0) { Gage[j].rainfall = Gage[Gage[j].coGage].rainfall; return; } // --- otherwise march through rainfall record until date t is bracketed t += OneSecond; for (;;) { // --- no rainfall if no interval start date if ( Gage[j].startDate == NO_DATE ) { Gage[j].rainfall = 0.0; return; } // --- no rainfall if time is before interval start date if ( t < Gage[j].startDate ) { Gage[j].rainfall = 0.0; return; } // --- use current rainfall if time is before interval end date if ( t < Gage[j].endDate ) { return; } // --- no rainfall if t >= interval end date & no next interval exists if ( Gage[j].nextDate == NO_DATE ) { Gage[j].rainfall = 0.0; return; } // --- no rainfall if t > interval end date & < next interval date if ( t < Gage[j].nextDate ) { Gage[j].rainfall = 0.0; return; } // --- otherwise update next rainfall interval date Gage[j].startDate = Gage[j].nextDate; Gage[j].endDate = datetime_addSeconds(Gage[j].startDate, Gage[j].rainInterval); Gage[j].rainfall = Gage[j].nextRainfall; if ( !getNextRainfall(j) ) Gage[j].nextDate = NO_DATE; } }
void gage_initState(int j) // // Input: j = rain gage index // Output: none // Purpose: initializes state of rain gage. // { int i, k; // --- assume gage not used by any subcatchment // (will be updated in subcatch_initState) Gage[j].isUsed = FALSE; Gage[j].rainfall = 0.0; //(5.0.010 - LR) Gage[j].reportRainfall = 0.0; //(5.0.010 - LR) if ( IgnoreRainfall ) return; //(5.0.010 - LR) // --- for gage with file data: if ( Gage[j].dataSource == RAIN_FILE ) { // --- set current file position to start of period of record Gage[j].currentFilePos = Gage[j].startFilePos; // --- assign units conversion factor // (rain depths on interface file are in inches) if ( UnitSystem == SI ) Gage[j].unitsFactor = MMperINCH; } // --- for gage with time series data, determine if gage uses // same time series as another gage with lower index // (no check required for gages sharing same rain file) if ( Gage[j].dataSource == RAIN_TSERIES ) { k = Gage[j].tSeries; for (i=0; i<j; i++) { if ( Gage[i].dataSource == RAIN_TSERIES && Gage[i].tSeries == k) { Gage[j].coGage = i; return; } } } // --- get first & next rainfall values if ( getFirstRainfall(j) ) { // --- find date at end of starting rain interval Gage[j].endDate = datetime_addSeconds( Gage[j].startDate, Gage[j].rainInterval); // --- if rainfall record begins after start of simulation, if ( Gage[j].startDate > StartDateTime ) { // --- make next rainfall date the start of the rain record Gage[j].nextDate = Gage[j].startDate; Gage[j].nextRainfall = Gage[j].rainfall; // --- make start of current rain interval the simulation start Gage[j].startDate = StartDateTime; Gage[j].endDate = Gage[j].nextDate; Gage[j].rainfall = 0.0; } // --- otherwise find next recorded rainfall else if ( !getNextRainfall(j) ) Gage[j].nextDate = NO_DATE; } else Gage[j].startDate = NO_DATE; }