Exemplo n.º 1
0
void climate_setState(DateTime theDate)
//
//  Input:   theDate = simulation date
//  Output:  none
//  Purpose: sets climate variables for current date.
//
{
    if ( Fclimate.mode == USE_FILE ) updateFileValues(theDate);
    if ( Temp.dataSource != NO_TEMP ) setTemp(theDate);
    setEvap(theDate);
    setWind(theDate);
    Adjust.rainFactor = Adjust.rain[datetime_monthOfYear(theDate)-1];          //(5.1.007)
    Adjust.hydconFactor = Adjust.hydcon[datetime_monthOfYear(theDate)-1];      //(5.1.008)
    setNextEvapDate(theDate);                                                  //(5.1.008)
}
Exemplo n.º 2
0
void addDryWeatherInflows(DateTime currentDate)
//
//  Input:   currentDate = current date/time
//  Output:  none
//  Purpose: adds dry weather inflows to nodes at current date.
//
{
    int      j, p;
    int      month, day, hour;
    double   q, w;
    TDwfInflow* inflow;

    // --- get month (zero-based), day-of-week (zero-based),
    //     & hour-of-day for routing date/time
    month = datetime_monthOfYear(currentDate) - 1;
    day   = datetime_dayOfWeek(currentDate) - 1;
    hour  = datetime_hourOfDay(currentDate);

    // --- for each node with a defined dry weather inflow
    for (j = 0; j < Nobjects[NODE]; j++)
    {
        inflow = Node[j].dwfInflow;
        if ( !inflow ) continue;

        // --- get flow inflow (i.e., the inflow whose param code is -1)
        q = 0.0;
        while ( inflow )
        {
            if ( inflow->param < 0 )
            {
                q = inflow_getDwfInflow(inflow, month, day, hour);
                break;
            }
            inflow = inflow->next;
        }
        if ( fabs(q) < FLOW_TOL ) q = 0.0;

        // --- add flow inflow to node's lateral inflow
        Node[j].newLatFlow += q;
        massbal_addInflowFlow(DRY_WEATHER_INFLOW, q);

        // --- get pollutant mass inflows
        inflow = Node[j].dwfInflow;
        while ( inflow )
        {
            if ( inflow->param >= 0 )
            {
                p = inflow->param;
                w = q * inflow_getDwfInflow(inflow, month, day, hour);
                Node[j].newQual[p] += w;
                massbal_addInflowQual(DRY_WEATHER_INFLOW, p, w);
            }
            inflow = inflow->next;
        }
    }
}
Exemplo n.º 3
0
void getEvapRates(Project* project, double theta, double upperDepth)
//
//  Input:   theta      = moisture content of upper zone
//           upperDepth = depth of upper zone (ft)
//  Output:  none
//  Purpose: computes evapotranspiration out of upper & lower zones.
//
{
    int    p, month;
    double f;
    double lowerFrac, upperFrac;

    // --- no project->GW evaporation when infiltration is occurring
    project->UpperEvap = 0.0;
    project->LowerEvap = 0.0;
    if ( project->Infil > 0.0 ) return;

    // --- get monthly-adjusted upper zone evap fraction
    upperFrac = project->A.upperEvapFrac;
    f = 1.0;
    p = project->A.upperEvapPat;
    if ( p >= 0 )
    {
        month = datetime_monthOfYear(getDateTime(project,project->NewRunoffTime));
        f = project->Pattern[p].factor[month-1];
    }
    upperFrac *= f;

    // --- upper zone evaporation requires that soil moisture
    //     be above the wilting point
    if ( theta > project->A.wiltingPoint )
    {
        // --- actual evap is upper zone fraction applied to max. potential
        //     rate, limited by the available rate after any surface evap 
        project->UpperEvap = upperFrac * project->MaxEvap;
        project->UpperEvap = MIN(project->UpperEvap, project->AvailEvap);
    }

    // --- check if lower zone evaporation is possible
    if ( project->A.lowerEvapDepth > 0.0 )
    {
        // --- find the fraction of the lower evaporation depth that
        //     extends into the saturated lower zone
        lowerFrac = (project->A.lowerEvapDepth - upperDepth) / project->A.lowerEvapDepth;
        lowerFrac = MAX(0.0, lowerFrac);
        lowerFrac = MIN(lowerFrac, 1.0);

        // --- make the lower zone evap rate proportional to this fraction
        //     and the evap not used in the upper zone
        project->LowerEvap = lowerFrac * (1.0 - upperFrac) * project->MaxEvap;
        project->LowerEvap = MIN(project->LowerEvap, (project->AvailEvap - project->UpperEvap));
    }
}
Exemplo n.º 4
0
void setEvap(DateTime theDate)
//
//  Input:   theDate = simulation date
//  Output:  none
//  Purpose: sets evaporation rate (ft/sec) for a specified date.
//
{
    int k;
    int mon = datetime_monthOfYear(theDate);                                   //(5.1.007)

    switch ( Evap.type )
    {
      case CONSTANT_EVAP:
        Evap.rate = Evap.monthlyEvap[0] / UCF(EVAPRATE);
        break;

      case MONTHLY_EVAP:
        Evap.rate = Evap.monthlyEvap[mon-1] / UCF(EVAPRATE);
        break;

      case TIMESERIES_EVAP:
        if ( theDate >= NextEvapDate )
            Evap.rate = NextEvapRate / UCF(EVAPRATE);
        break;

      case FILE_EVAP:
        Evap.rate = FileValue[EVAP] / UCF(EVAPRATE);
        Evap.rate *= Evap.panCoeff[mon-1];
        break;

      case TEMPERATURE_EVAP:
        Evap.rate = FileValue[EVAP] / UCF(EVAPRATE);
        break;

      default: Evap.rate = 0.0;
    }

    // --- apply climate change adjustment                                     //(5.1.007)
    Evap.rate += Adjust.evap[mon-1];                                           //(5.1.007)

    // --- set soil recovery factor
    Evap.recoveryFactor = 1.0;
    k = Evap.recoveryPattern;
    if ( k >= 0 && Pattern[k].type == MONTHLY_PATTERN )
    {
        Evap.recoveryFactor = Pattern[k].factor[mon-1];                        //(5.1.007)
    }
}
Exemplo n.º 5
0
void setEvap(DateTime theDate)
//
//  Input:   theDate = simulation date
//  Output:  none
//  Purpose: sets evaporation rate (ft/sec) for a specified date.
//
{
    int yr, mon, day, k;

    switch ( Evap.type )
    {
      case CONSTANT_EVAP:
        Evap.rate = Evap.monthlyEvap[0] / UCF(EVAPRATE);
        break;

      case MONTHLY_EVAP:
        datetime_decodeDate(theDate, &yr, &mon, &day);
        Evap.rate = Evap.monthlyEvap[mon-1] / UCF(EVAPRATE);
        break;

      case TIMESERIES_EVAP:
        if ( theDate >= NextEvapDate )
            Evap.rate = NextEvapRate / UCF(EVAPRATE);
        break;

      case FILE_EVAP:
        Evap.rate = FileValue[EVAP] / UCF(EVAPRATE);
        datetime_decodeDate(theDate, &yr, &mon, &day);
        Evap.rate *= Evap.panCoeff[mon-1];
        break;

      case TEMPERATURE_EVAP:
        Evap.rate = FileValue[EVAP] / UCF(EVAPRATE);
        break;

      default: Evap.rate = 0.0;
    }

    // --- set soil recovery factor
    Evap.recoveryFactor = 1.0;
    k = Evap.recoveryPattern;
    if ( k >= 0 && Pattern[k].type == MONTHLY_PATTERN )
    {
        mon = datetime_monthOfYear(theDate) - 1;
        Evap.recoveryFactor = Pattern[k].factor[mon];
    }
}
Exemplo n.º 6
0
int evaluatePremise(struct TPremise* p, DateTime theDate, DateTime theTime,
                    DateTime elapsedTime, double tStep)
//
//  Input:   p = a control rule premise condition
//           theDate = the current simulation date
//           theTime = the current simulation time of day
//           elpasedTime = decimal days since the start of the simulation
//           tStep = current time step (days)                                  //(5.0.013 - LR)
//  Output:  returns TRUE if the condition is true or FALSE otherwise
//  Purpose: evaluates the truth of a control rule premise condition.
//
{
    int i = p->node;
    int j = p->link;
    double head;

    switch ( p->attribute )
    {
      case r_TIME:
        return checkTimeValue(p, elapsedTime, elapsedTime + tStep);

      case r_DATE:
        return checkValue(p, theDate);

      case r_CLOCKTIME:
        return checkTimeValue(p, theTime, theTime + tStep);

      case r_DAY:                                                              //(5.0.014 - LR)
        return checkValue(p, datetime_dayOfWeek(theDate));                     //(5.0.014 - LR)

      case r_MONTH:                                                            //(5.0.014 - LR)
        return checkValue(p, datetime_monthOfYear(theDate));                   //(5.0.014 - LR)

      case r_STATUS:
        if ( j < 0 || Link[j].type != PUMP ) return FALSE;
        else return checkValue(p, Link[j].setting);
        
      case r_SETTING:
        if ( j < 0 || (Link[j].type != ORIFICE && Link[j].type != WEIR) )
            return FALSE;
        else return checkValue(p, Link[j].setting);

      case r_FLOW:
        if ( j < 0 ) return FALSE;
        else return checkValue(p, Link[j].direction*Link[j].newFlow*UCF(FLOW));//(5.0.019 - LR)

      case r_DEPTH:
        if ( j >= 0 ) return checkValue(p, Link[j].newDepth*UCF(LENGTH));
        else if ( i >= 0 )
            return checkValue(p, Node[i].newDepth*UCF(LENGTH));
        else return FALSE;

      case r_HEAD:
        if ( i < 0 ) return FALSE;
        head = (Node[i].newDepth + Node[i].invertElev) * UCF(LENGTH);
        return checkValue(p, head);

      case r_INFLOW:
        if ( i < 0 ) return FALSE;
        else return checkValue(p, Node[i].newLatFlow*UCF(FLOW));

      default: return FALSE;
    }
}
Exemplo n.º 7
0
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);
        }
    }
}
Exemplo n.º 8
0
void setTemp(DateTime theDate)
//
//  Input:   theDate = simulation date
//  Output:  none
//  Purpose: updates temperatures for new simulation date.
//
{
    int      j;                        // snow data object index
    int      k;                        // time series index
    int      mon;                      // month of year                        //(5.1.007)
    int      day;                      // day of year
    DateTime theDay;                   // calendar day
    double   hour;                     // hour of day
    double   tmp;                      // temporary temperature

    // --- see if a new day has started
    mon = datetime_monthOfYear(theDate);                                       //(5.1.007)
    theDay = floor(theDate);
    if ( theDay > LastDay )
    {
        // --- update min. & max. temps & their time of day
        day = datetime_dayOfYear(theDate);
        if ( Temp.dataSource == FILE_TEMP )
        {
            Tmin = FileValue[TMIN] + Adjust.temp[mon-1];                       //(5.1.007)
            Tmax = FileValue[TMAX] + Adjust.temp[mon-1];                       //(5.1.007)
            if ( Tmin > Tmax )
            {
                tmp = Tmin;
                Tmin = Tmax;
                Tmax = tmp;
            }
            updateTempTimes(day);
            if ( Evap.type == TEMPERATURE_EVAP )
            {
                updateTempMoveAve(Tmin, Tmax);                                 //(5.1.010)
                FileValue[EVAP] = getTempEvap(day, Tma.tAve, Tma.tRng);        //(5.1.010)
            }
        }

        // --- compute snow melt coefficients based on day of year
        Snow.season = sin(0.0172615*(day-81.0));
        for (j=0; j<Nobjects[SNOWMELT]; j++)
        {
            snow_setMeltCoeffs(j, Snow.season);
        }

        // --- update date of last day analyzed
        LastDay = theDate;
    }

    // --- for min/max daily temps. from climate file,
    //     compute hourly temp. by sinusoidal interp.
    if ( Temp.dataSource == FILE_TEMP )
    {
        hour = (theDate - theDay) * 24.0;
        if ( hour < Hrsr )
            Temp.ta = Tmin + Trng1/2.0 * sin(PI/Dydif * (Hrsr - hour));
        else if ( hour >= Hrsr && hour <= Hrss )
            Temp.ta = Tave + Trng * sin(PI/Dhrdy * (Hrday - hour));
        else
            Temp.ta = Tmax - Trng * sin(PI/Dydif * (hour - Hrss));
    }

    // --- for user-supplied temperature time series,
    //     get temperature value from time series
    if ( Temp.dataSource == TSERIES_TEMP )
    {
        k = Temp.tSeries;
        if ( k >= 0)
        {
            Temp.ta = table_tseriesLookup(&Tseries[k], theDate, TRUE);

            // --- convert from deg. C to deg. F if need be
            if ( UnitSystem == SI )
            {
                Temp.ta = (9./5.) * Temp.ta + 32.0;
            }

            // --- apply climate change adjustment factor                      //(5.1.007)
            Temp.ta += Adjust.temp[mon-1];                                     //(5.1.007)
        }
    }

    // --- compute saturation vapor pressure
    Temp.ea = 8.1175e6 * exp(-7701.544 / (Temp.ta + 405.0265) );
}