Esempio n. 1
0
double landuse_getExternalBuildup(Project* project, int i, int p, double buildup, double tStep)
//
//  Input:   i = landuse index
//           p = pollutant index
//           buildup = buildup at start of time step (mass/unit)
//           tStep = time step (sec)
//  Output:  returns pollutant buildup at end of time interval (mass/unit)
//  Purpose: finds pollutant buildup contributed by external loading over a
//           given time step.
//
{
    double maxBuildup = project->Landuse[i].buildupFunc[p].coeff[0];
    double sf = project->Landuse[i].buildupFunc[p].coeff[1];              // scaling factor
    int    ts = (int)floor(project->Landuse[i].buildupFunc[p].coeff[2]);  // time series index
    double rate = 0.0;

    // --- no buildup increment at start of simulation
    if (project->NewRunoffTime == 0.0) return 0.0;

    // --- get buildup rate (mass/unit/day) over the interval
    if ( ts >= 0 )
    {
        rate = sf * table_tseriesLookup(&project->Tseries[ts],
                                        getDateTime(project, project->NewRunoffTime), FALSE);
    }

    // --- compute buildup at end of time interval
    buildup = buildup + rate * tStep / SECperDAY;
    buildup = MIN(buildup, maxBuildup);
    return buildup;
}
Esempio n. 2
0
void  updateActionValue(struct TAction* a, DateTime currentTime, double dt)    //(5.0.012 - LR)
//
//  Input:   a = an action object
//           currentTime = current simulation date/time (days)                 //(5.0.013 - LR)
//           dt = time step (days)                                             //(5.0.013 - LR)
//  Output:  none
//  Purpose: updates value of actions found from Curves or Time Series.
//
{
    if ( a->curve >= 0 )
    {
        a->value = table_lookup(&Curve[a->curve], ControlValue);
    }
    else if ( a->tseries >= 0 )
    {
        a->value = table_tseriesLookup(&Tseries[a->tseries], currentTime, TRUE);
    }
    else if ( a->attribute == r_PID )
    {
        a->value = getPIDSetting(a, dt);
    }
}
Esempio n. 3
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];
        break;

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

      case TIMESERIES_EVAP:
        k = Evap.tSeries;
        Evap.rate = table_tseriesLookup(&Tseries[k], theDate, TRUE);
        break;

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

      default: Evap.rate = 0.0;
    }

    // --- convert rate from in/day (mm/day) to ft/sec
    Evap.rate /= UCF(EVAPRATE);
}
Esempio n. 4
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      day;                      // day of year
    DateTime theDay;                   // calendar day
    double   hour;                     // hour of day

    // --- see if a new day has started
    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];
            Tmax = FileValue[TMAX];
            updateTempTimes(day);
        }

        // --- 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;
            }
        }
    }

    // --- compute saturation vapor pressure
    Temp.ea = 8.1175e6 * exp(-7701.544 / (Temp.ta + 405.0265) );
}
Esempio n. 5
0
void outfall_setOutletDepth(int j, double yNorm, double yCrit, double z)
//
//  Input:   j = node index
//           yNorm = normal flow depth in outfall conduit (ft)
//           yCrit = critical flow depth in outfall conduit (ft)
//           z = height to outfall conduit invert (ft)
//  Output:  none
//  Purpose: sets water depth at an outfall node.
//
{
    double   x, y;                     // x,y values in table
    double   yNew;                     // new depth above invert elev. (ft)
    double   stage;                    // water elevation at outfall (ft)
    int      k;                        // table index
    int      i = Node[j].subIndex;     // outfall index
    DateTime currentDate;              // current date/time in days

    switch ( Outfall[i].type )
    {
      case FREE_OUTFALL:
        if ( z > 0.0 ) Node[j].newDepth = 0.0;
        else Node[j].newDepth = MIN(yNorm, yCrit);
        return;

      case NORMAL_OUTFALL:
        if ( z > 0.0 ) Node[j].newDepth = 0.0;
        else Node[j].newDepth = yNorm;
        return;

      case FIXED_OUTFALL:
        stage = Outfall[i].fixedStage;
        break;

      case TIDAL_OUTFALL:
        k = Outfall[i].tideCurve;
        table_getFirstEntry(&Curve[k], &x, &y);
        currentDate = NewRoutingTime / MSECperDAY;
        x += ( currentDate - floor(currentDate) ) * 24.0;
        stage = table_lookup(&Curve[k], x) / UCF(LENGTH);
        break;

      case TIMESERIES_OUTFALL:
        k = Outfall[i].stageSeries;
        currentDate = StartDateTime + NewRoutingTime / MSECperDAY;
        stage = table_tseriesLookup(&Tseries[k], currentDate, TRUE) /
                UCF(LENGTH);
        break;
      default: stage = Node[j].invertElev;
    }

    // --- now determine depth at node given outfall stage elev.
 
    // --- let critical flow depth be min. of critical & normal depth
    yCrit = MIN(yCrit, yNorm);

    // --- if elev. of critical depth is below outfall stage elev. then
    //     the outfall stage determines node depth
    if ( yCrit + z + Node[j].invertElev < stage )
    {
        yNew = stage - Node[j].invertElev;
    }

    // --- otherwise if the outfall conduit lies above the outfall invert
    else if ( z > 0.0 )
    {
        // --- if the outfall stage lies below the bottom of the outfall
        //     conduit then the result is distance from node invert to stage
        if ( stage < Node[j].invertElev + z )
            yNew = MAX(0.0, (stage - Node[j].invertElev));

        // --- otherwise stage lies between bottom of conduit and critical
        //     depth in conduit so result is elev. of critical depth
        else
            yNew = z + yCrit;
    }

    // --- and for case where there is no conduit offset and outfall stage
    //     lies below critical depth, then node depth = critical depth 
    else yNew = yCrit;
    Node[j].newDepth = yNew;
}