Ejemplo n.º 1
0
double subcatch_getRunoff(int j, double tStep)
//
//  Input:   j = subcatchment index
//           tStep = time step (sec)
//  Output:  returns total runoff produced by subcatchment (ft/sec)
//  Purpose: Computes runoff & new storage depth for subcatchment.
//
//  The 'runoff' value returned by this function is the total runoff
//  generated (in ft/sec) by the subcatchment before any internal
//  re-routing is applied. It is used to compute pollutant washoff.
//
//  The 'outflow' value computed here (in cfs) is the surface runoff
//  that actually leaves the subcatchment after any LID controls are
//  applied and is saved to Subcatch[j].newRunoff. 
//
{
    int    i;                          // subarea index
    double nonLidArea;                 // non-LID portion of subcatch area (ft2)
    double area;                       // sub-area or subcatchment area (ft2)
    double netPrecip[3];               // subarea net precipitation (ft/sec)
    double vRain;                      // rainfall (+ snowfall) volume (ft3)
    double vRunon    = 0.0;            // runon volume from other areas (ft3)
    double vOutflow  = 0.0;            // runoff volume leaving subcatch (ft3)
    double runoff    = 0.0;            // total runoff flow on subcatch (cfs)
    double evapRate  = 0.0;            // potential evaporation rate (ft/sec)

    // --- initialize shared water balance variables
    Vevap     = 0.0;
    Vpevap    = 0.0;
    Vinfil    = 0.0;
    Voutflow  = 0.0;
    VlidIn    = 0.0;
    VlidInfil = 0.0;
    VlidOut   = 0.0;
    VlidDrain = 0.0;
    VlidReturn = 0.0;

    // --- find volume of inflow to non-LID portion of subcatchment as existing
    //     ponded water + any runon volume from upstream areas;
    //     rainfall and snowmelt will be added as each sub-area is analyzed
    nonLidArea = Subcatch[j].area - Subcatch[j].lidArea;
    vRunon = Subcatch[j].runon * tStep * nonLidArea;
    Vinflow = vRunon + subcatch_getDepth(j) * nonLidArea;

////  Added to release 5.1.009.  ////                                          //(5.1.009)
    // --- find LID runon only if LID occupies full subcatchment
    if ( nonLidArea == 0.0 )
        vRunon = Subcatch[j].runon * tStep * Subcatch[j].area;
////

    // --- get net precip. (rainfall + snowfall + snowmelt) on the 3 types
    //     of subcatchment sub-areas and update Vinflow with it
    getNetPrecip(j, netPrecip, tStep);

    // --- find potential evaporation rate
    if ( Evap.dryOnly && Subcatch[j].rainfall > 0.0 ) evapRate = 0.0;
    else evapRate = Evap.rate;

    // --- examine each type of sub-area (impervious w/o depression storage,
    //     impervious w/ depression storage, and pervious)
    if ( nonLidArea > 0.0 ) for (i = IMPERV0; i <= PERV; i++)
    {
        // --- get runoff from sub-area updating Vevap, Vpevap,
        //     Vinfil & Voutflow)
        area = nonLidArea * Subcatch[j].subArea[i].fArea;
        Subcatch[j].subArea[i].runoff =
            getSubareaRunoff(j, i, area, netPrecip[i], evapRate, tStep);
        runoff += Subcatch[j].subArea[i].runoff * area;
    }

    // --- evaluate any LID treatment provided (updating Vevap,
    //     Vpevap, VlidInfil, VlidIn, VlidOut, & VlidDrain)
    if ( Subcatch[j].lidArea > 0.0 )
    {
        lid_getRunoff(j, tStep);
    }

    // --- update groundwater levels & flows if applicable
    if ( !IgnoreGwater && Subcatch[j].groundwater )
    {
        gwater_getGroundwater(j, Vpevap, Vinfil, tStep);
    }

    // --- save subcatchment's total loss rates (ft/s)
    area = Subcatch[j].area;
    Subcatch[j].evapLoss = Vevap / tStep / area;
    Subcatch[j].infilLoss = (Vinfil + VlidInfil) / tStep / area;

    // --- find net surface runoff volume
    //     (VlidDrain accounts for LID drain flows)
    vOutflow = Voutflow      // runoff from all non-LID areas
               - VlidIn      // runoff treated by LID units
               + VlidOut;    // runoff from LID units
    Subcatch[j].newRunoff = vOutflow / tStep;

    // --- obtain external precip. volume (without any snowmelt)
    vRain = Subcatch[j].rainfall * tStep * area;

    // --- update the cumulative stats for this subcatchment
    stats_updateSubcatchStats(j, vRain, vRunon, Vevap, Vinfil + VlidInfil,
                              vOutflow + VlidDrain,
                              Subcatch[j].newRunoff + VlidDrain/tStep);

    // --- include this subcatchment's contribution to overall flow balance
    //     only if its outlet is a drainage system node
    if ( Subcatch[j].outNode == -1 && Subcatch[j].outSubcatch != j )
    {
        vOutflow = 0.0;
    }

    // --- update mass balances
    massbal_updateRunoffTotals(RUNOFF_RAINFALL, vRain);
    massbal_updateRunoffTotals(RUNOFF_EVAP, Vevap);
    massbal_updateRunoffTotals(RUNOFF_INFIL, Vinfil+VlidInfil);
    massbal_updateRunoffTotals(RUNOFF_RUNOFF, vOutflow);

    // --- return area-averaged runoff (ft/s)
    return runoff / area;
}
Ejemplo n.º 2
0
double subcatch_getRunoff(int j, double tStep)
//
//  Input:   j = subcatchment index
//           tStep = time step (sec)
//  Output:  returns total runoff produced by subcatchment (ft/sec)
//  Purpose: Computes runoff & new storage depth for subcatchment.
//
{
    int    i;                          // subarea index
    double area;                       // portion of subcatchment area (ft2)
    double netPrecip[3];               // subarea net precipitation (ft/sec)
    double rainVol     = 0.0;          // rain volume (ft3)
    double evapVol     = 0.0;          // evaporation volume (ft3)
    double infilVol    = 0.0;          // infiltration volume (ft3)
    double outflowVol  = 0.0;          // runoff volume leaving subcatch (ft3)
    double outflow     = 0.0;          // runoff rate leaving subcatch (cfs)
    double runoff      = 0.0;          // total runoff rate on subcatch (ft/sec)
    double pervEvapVol = 0.0;          // evaporation over pervious area (ft3)
    double evapRate    = 0.0;          // max. evaporation rate (ft/sec)

    // NOTE: The 'runoff' value returned by this function is the total runoff
    //       generated (in ft/sec) by the subcatchment before any internal
    //       re-routing is applied. It is used in the Exponential Washoff
    //       function to compute pollutant washoff. The 'outflow' value
    //       computed here (in cfs) is the runoff that actually leaves the
    //       subcatchment (which can be reduced by internal re-routing and
    //       LID controls) and is saved to Subcatch[j].newRunoff.

    // --- save current depth of ponded water over entire subcatchment
    Vponded = subcatch_getDepth(j) * Subcatch[j].area;

    // --- get net precipitation (rainfall + snowmelt) on subcatchment
    getNetPrecip(j, netPrecip, tStep);
    if ( Evap.dryOnly && Subcatch[j].rainfall > 0.0 ) evapRate = 0.0;
    else evapRate = Evap.rate;

    // --- initialize runoff rates
    outflow = 0.0;
    runoff = 0.0;

    // --- examine each type of sub-area
    for (i = IMPERV0; i <= PERV; i++)
    {
        // --- check that sub-area type exists
        area = (Subcatch[j].area - Subcatch[j].lidArea) *
               Subcatch[j].subArea[i].fArea;
        if ( area > 0.0 )
        {
            // --- get runoff rate from sub-area
            getSubareaRunoff(j, i, netPrecip[i], evapRate, tStep);
            runoff += Subcatch[j].subArea[i].runoff * area;

            // --- update components of volumetric water balance (in ft3)
            //Subcatch[j].losses += Losses * area;
            rainVol    += netPrecip[i] * tStep * area;
            outflow    += Outflow * area;
            evapVol    += Vevap * area;
            infilVol   += Vinfil * area;

            // --- save evap losses from pervious area
            //     (needed for groundwater modeling)
            if ( i == PERV ) pervEvapVol += Vevap * area;
        }
    }

    // --- evaluate LID treatment as if it were another type of sub-area
    //     while updating outflow, evap volumes, & infil volumes
    if ( Subcatch[j].lidArea > 0.0 )
        runoff += lid_getRunoff(j, &outflow, &evapVol, &pervEvapVol,
                                &infilVol, tStep);

    // --- update groundwater levels & flows if applicable
    if (!IgnoreGwater && Subcatch[j].groundwater )
        gwater_getGroundwater(j, pervEvapVol, infilVol, tStep);

    // --- save subcatchment's outflow (cfs) & total loss rates (ft/s)
    area = Subcatch[j].area;
    Subcatch[j].newRunoff = outflow;
    Subcatch[j].evapLoss = evapVol / tStep / area;
    Subcatch[j].infilLoss = infilVol / tStep / area;

    // --- save volumes (ft3) for use in pollutant washoff calculation
    Vrain = rainVol;
    Vevap = evapVol;
    Vinfil = infilVol;
    Voutflow = outflow * tStep;
    Vrunon = Subcatch[j].runon * tStep * area;

    // --- compute water flux volumes over the time step
    rainVol = Subcatch[j].rainfall * tStep * area;
    stats_updateSubcatchStats(j, rainVol, Vrunon, Vevap, Vinfil,
                              Voutflow, outflow);

    // --- update system flow balance
    //     (system outflow is 0 if outlet is another subcatch)
    outflowVol = Voutflow;
    if ( Subcatch[j].outNode == -1 && Subcatch[j].outSubcatch != j )
    {
        outflowVol = 0.0;
    }
    massbal_updateRunoffTotals(rainVol, evapVol, infilVol, outflowVol);

    // --- return area-averaged runoff (ft/s)
    return runoff / area;
}