Пример #1
0
void updatePondedQual(int j, double wRunon[], double pondedQual[], double tStep)
{
    int    p;
    double c;
    double vIn;
    double wPpt, wInfil, w1;
    double bmpRemoval;
    int    isDry;

    // --- total inflow volume
    vIn = Vrain + Vrunon;

    // --- for dry conditions
    if ( Vponded + vIn == 0.0 ) isDry = 1;
    else isDry = 0;

    // --- analyze each pollutant
    for (p = 0; p < Nobjects[POLLUT]; p++)
    {
        // --- update mass balance for direct deposition
        wPpt = Pollut[p].pptConcen * LperFT3 * Vrain;                          //(5.1.006 - MT)
        massbal_updateLoadingTotals(DEPOSITION_LOAD, p, wPpt * Pollut[p].mcf);

        // --- surface is dry and has no inflow -- add any remaining mass
        //     to overall mass balance's FINAL_LOAD category
        if ( isDry )
        {
            massbal_updateLoadingTotals(FINAL_LOAD, p,
                                        pondedQual[p] * Pollut[p].mcf);
            pondedQual[p] = 0.0;
            OutflowLoad[p] = 0.0;
        }
        else
        {
            // --- find concen. of ponded water
            w1 = pondedQual[p] + wPpt + wRunon[p]*tStep;
            c = w1 / (Vponded + vIn);

            // --- mass lost to infiltration
            wInfil = c * Vinfil;
            wInfil = MIN(wInfil, w1);
            massbal_updateLoadingTotals(INFIL_LOAD, p, wInfil * Pollut[p].mcf);
            w1 -= wInfil;

            // --- mass lost to outflow
            OutflowLoad[p] = MIN(w1, (c*Voutflow));
            w1 -= OutflowLoad[p];

            // --- reduce outflow load by average BMP removal
            bmpRemoval = landuse_getAvgBmpEffic(j, p) * OutflowLoad[p];
            massbal_updateLoadingTotals(BMP_REMOVAL_LOAD, p,
                                        bmpRemoval*Pollut[p].mcf);
            OutflowLoad[p] -= bmpRemoval;

            // --- update ponded mass
            pondedQual[p] = c * subcatch_getDepth(j) * Subcatch[j].area;       //(5.1.006)
        }
    }
}
Пример #2
0
double landuse_getWashoffLoad(Project* project, int i, int p, double area,
                              TLandFactor landFactor[], double runoff, double vOutflow)
//
//  Input:   i = land use index
//           p = pollut. index
//           area = sucatchment area (ft2)
//           landFactor[] = array of land use data for subcatchment
//           runoff = runoff flow generated by subcatchment (ft/sec)
//           vOutflow = runoff volume leaving the subcatchment (ft3)
//  Output:  returns pollutant runoff load (mass)
//  Purpose: computes pollutant load generated by a land use over a time step.
//
{
    double landuseArea;      // area of current land use (ft2)
    double buildup;          // current pollutant buildup (lb or kg)
    double washoffQual;      // pollutant concentration in washoff (mass/ft3)
    double washoffLoad;      // pollutant washoff load over time step (lb or kg)
    double bmpRemoval;       // pollutant load removed by BMP treatment (lb or kg)

    // --- compute concen. of pollutant in washoff (mass/ft3)
    buildup = landFactor[i].buildup[p];
    landuseArea = landFactor[i].fraction * area;
    washoffQual = landuse_getWashoffQual(project, i, p, buildup, runoff, landuseArea);

    // --- compute washoff load exported (lbs or kg) from landuse
    //     (project->Pollut[].mcf converts from mg (or ug) mass units to lbs (or kg)
    washoffLoad = washoffQual * vOutflow * landuseArea / area * project->Pollut[p].mcf;

    // --- if buildup modelled, reduce it by amount of washoff
    if ( project->Landuse[i].buildupFunc[p].funcType != NO_BUILDUP ||
            buildup > washoffLoad )
    {
        washoffLoad = MIN(washoffLoad, buildup);
        buildup -= washoffLoad;
        landFactor[i].buildup[p] = buildup;
    }

    // --- otherwise add washoff to buildup mass balance totals
    //     so that things will balance
    else
    {
        massbal_updateLoadingTotals(project,BUILDUP_LOAD, p, washoffLoad);
        landFactor[i].buildup[p] = 0.0;
    }

    // --- apply any BMP removal to washoff
    bmpRemoval = project->Landuse[i].washoffFunc[p].bmpEffic * washoffLoad;
    if ( bmpRemoval > 0.0 )
    {
        massbal_updateLoadingTotals(project,BMP_REMOVAL_LOAD, p, bmpRemoval);
        washoffLoad -= bmpRemoval;
    }

    // --- return washoff load converted back to mass (mg or ug)
    return washoffLoad / project->Pollut[p].mcf;
}
Пример #3
0
float landuse_getCoPollutLoad(int p, float washoff[], float tStep)
//
//  Input:   p = pollutant index
//           washoff = pollut. washoff rate (mass/sec)
//           tStep = time step (sec)
//  Output:  returns washoff mass added by co-pollutant relation (mass/sec)
//  Purpose: finds washoff mass added by a co-pollutant of a given pollutant.
//
{
    int   k;
    float w;
    float load;

    // --- check if pollutant p has a co-pollutant k
    k = Pollut[p].coPollut;
    if ( k >= 0 )
    {
        // --- compute addition to washoff from co-pollutant
        w = Pollut[p].coFraction * washoff[k];

        // --- add to mass balance totals
        load = w * tStep * Pollut[p].mcf;
        massbal_updateLoadingTotals(BUILDUP_LOAD, p, load);
        return w;
    }
    return 0.0;
}
Пример #4
0
double landuse_getCoPollutLoad(Project* project, int p, double washoff[])
//
//  Input:   p = pollutant index
//           washoff = pollut. washoff rate (mass/sec)
//  Output:  returns washoff mass added by co-pollutant relation (mass)
//  Purpose: finds washoff mass added by a co-pollutant of a given pollutant.
//
{
    int    k;
    double w;

    // --- check if pollutant p has a co-pollutant k
    k = project->Pollut[p].coPollut;
    if ( k >= 0 )
    {
        // --- compute addition to washoff from co-pollutant
        w = project->Pollut[p].coFraction * washoff[k];

        // --- add washoff to buildup mass balance totals
        //     so that things will balance
        massbal_updateLoadingTotals(project,BUILDUP_LOAD, p, w * project->Pollut[p].mcf);
        return w;
    }
    return 0.0;
}
Пример #5
0
void subcatch_sweepBuildup(int j, DateTime aDate)
//
//  Input:   j = subcatchment index
//  Output:  none
//  Purpose: reduces pollutant buildup over a subcatchment if sweeping occurs.
//
{
    int     i;                         // land use index
    int     p;                         // pollutant index
    double  oldBuildup;                // buildup before sweeping (lbs or kg)
    double  newBuildup;                // buildup after sweeping (lbs or kg)

    // --- no sweeping if there is snow on plowable impervious area
    if ( Subcatch[j].snowpack != NULL &&
            Subcatch[j].snowpack->wsnow[IMPERV0] > MIN_TOTAL_DEPTH ) return;

    // --- consider each land use
    for (i = 0; i < Nobjects[LANDUSE]; i++)
    {
        // --- skip land use if not in subcatchment
        if ( Subcatch[j].landFactor[i].fraction == 0.0 ) continue;

        // --- see if land use is subject to sweeping
        if ( Landuse[i].sweepInterval == 0.0 ) continue;

        // --- see if sweep interval has been reached
        if ( aDate - Subcatch[j].landFactor[i].lastSwept >=
                Landuse[i].sweepInterval )
        {

            // --- update time when last swept
            Subcatch[j].landFactor[i].lastSwept = aDate;

            // --- examine each pollutant
            for (p = 0; p < Nobjects[POLLUT]; p++)
            {
                // --- reduce buildup by the fraction available
                //     times the sweeping effic.
                oldBuildup = Subcatch[j].landFactor[i].buildup[p];
                newBuildup = oldBuildup * (1.0 - Landuse[i].sweepRemoval *
                                           Landuse[i].washoffFunc[p].sweepEffic);
                newBuildup = MIN(oldBuildup, newBuildup);
                newBuildup = MAX(0.0, newBuildup);
                Subcatch[j].landFactor[i].buildup[p] = newBuildup;

                // --- update mass balance totals
                massbal_updateLoadingTotals(SWEEPING_LOAD, p,
                                            oldBuildup - newBuildup);
            }
        }
    }
}
Пример #6
0
void subcatch_getBuildup(int j, double tStep)
//
//  Input:   j = subcatchment index
//           tStep = time step (sec)
//  Output:  none
//  Purpose: adds to pollutant buildup on subcatchment.
//
{
    int     i;                         // land use index
    int     p;                         // pollutant index
    double  f;                         // land use fraction
    double  area;                      // land use area (acres or hectares)
    double  curb;                      // land use curb length (user units)
    double  oldBuildup;                // buildup at start of time step
    double  newBuildup;                // buildup at end of time step

    // --- consider each landuse
    for (i = 0; i < Nobjects[LANDUSE]; i++)
    {
        // --- skip landuse if not in subcatch
        f = Subcatch[j].landFactor[i].fraction;
        if ( f == 0.0 ) continue;

        // --- get land area (in acres or hectares) & curb length
        area = f * Subcatch[j].area * UCF(LANDAREA);
        curb = f * Subcatch[j].curbLength;

        // --- examine each pollutant
        for (p = 0; p < Nobjects[POLLUT]; p++)
        {
            // --- see if snow-only buildup is in effect
            if (Pollut[p].snowOnly
                    && Subcatch[j].newSnowDepth < 0.001/12.0) continue;

            // --- use land use's buildup function to update buildup amount
            oldBuildup = Subcatch[j].landFactor[i].buildup[p];
            newBuildup = landuse_getBuildup(i, p, area, curb, oldBuildup,
                                            tStep);
            newBuildup = MAX(newBuildup, oldBuildup);
            Subcatch[j].landFactor[i].buildup[p] = newBuildup;
            massbal_updateLoadingTotals(BUILDUP_LOAD, p,
                                        (newBuildup - oldBuildup));
        }
    }
}
Пример #7
0
void runoff_getOutfallRunon(double tStep)
//
//  Input:   tStep = previous runoff time step (sec)
//  Output:  none
//  Purpose: adds flow and pollutant loads leaving drainage system outfalls
//           during the previous runoff time step to designated subcatchments.
//
{
    int i, k, p;
    double w;

    // --- examine each outfall node
    for (i = 0; i < Nnodes[OUTFALL]; i++)
    {
        // --- ignore node if outflow not re-routed onto a subcatchment
        k = Outfall[i].routeTo;
        if ( k < 0 ) continue;
        if ( Subcatch[k].area == 0.0 ) continue;

        // --- add outfall's flow to subcatchment as runon and re-set routed
        //     flow volume to 0
        subcatch_addRunonFlow(k, Outfall[i].vRouted/tStep);
        massbal_updateRunoffTotals(RUNOFF_RUNON, Outfall[i].vRouted);
        Outfall[i].vRouted = 0.0;

        // --- add outfall's pollutant load on to subcatchment's wet
        //     deposition load and re-set routed load to 0
        //     (Subcatch.newQual is being used as a temporary load accumulator)
        for (p = 0; p < Nobjects[POLLUT]; p++)
        {
            w = Outfall[i].wRouted[p] * LperFT3;
            massbal_updateLoadingTotals(DEPOSITION_LOAD, p, w * Pollut[p].mcf);
            Subcatch[k].newQual[p] += w / tStep;
            Outfall[i].wRouted[p] = 0.0;
        }
    }
}
Пример #8
0
float landuse_getRunoffLoad(int i, int p, float area, TLandFactor landFactor[], 
                            float runoff, float tStep)
//
//  Input:   i = land use index
//           p = pollut. index
//           area = area devoted to land use (ft2)
//           landFactor[] = array of land use data for subcatchment
//           runoff = runoff flow on subcatchment (ft/sec)
//           tStep = time step (sec)
//  Output:  returns runoff load for pollutant (mass/sec)
//  Purpose: computes pollutant load generated by a specific land use.
//
{
    float buildup;
    float washoff;

    // --- compute washoff mass/sec for this pollutant
    buildup = landFactor[i].buildup[p];
    washoff = landuse_getWashoffMass(i, p, buildup, runoff, area);
		
	//added
	if(strncmp(strTSS, "", MAXFNAME) != 0 && Pollut[p].sedflag > 0) 
	{
		// check the sediment class
		if (Pollut[p].sedflag == 1)
		{
			// sand
			buildup *= Landuse[i].frc_sand;
			washoff *= Landuse[i].frc_sand;
		}
		else if (Pollut[p].sedflag == 2)
		{
			// silt
			buildup *= Landuse[i].frc_silt;
			washoff *= Landuse[i].frc_silt;
		}
		else if (Pollut[p].sedflag == 3)
		{
			// clay
			buildup *= Landuse[i].frc_clay;
			washoff *= Landuse[i].frc_clay;
		}
	}
			
    // --- convert washoff to lbs (or kg) over time step so that
    //     buildup and mass balances can be adjusted
    //     (Pollut[].mcf converts from concentration mass units
    //      to either lbs or kg)
    washoff *= tStep * Pollut[p].mcf;

    // --- if buildup modelled, reduce it by amount of washoff
    if ( Landuse[i].buildupFunc[p].funcType != NO_BUILDUP )
    {
        washoff = MIN(washoff, buildup);
        buildup -= washoff;
        landFactor[i].buildup[p] = buildup;
    }

    // --- otherwise add washoff to buildup mass balance totals
    //     so that things will balance
    else massbal_updateLoadingTotals(BUILDUP_LOAD, p, washoff);

    // --- return washoff converted back to mass/sec
    return washoff / tStep / Pollut[p].mcf;
}
Пример #9
0
void  subcatch_getWashoff(int j, double runoff, double tStep)
//
//  Input:   j = subcatchment index
//           runoff = total subcatchment runoff (ft/sec)
//           tStep = time step (sec)
//  Output:  none
//  Purpose: computes new runoff quality for subcatchment.
//
//  Considers two separate pollutant generating streams that are combined
//  together:
//  1. complete mix mass balance of pollutants in surface ponding due to
//     runon, wet deposition, infil., & evap.
//  2. washoff of pollutant buildup as described by the project's land
//     use washoff functions.
//
{
    int    i, p;
    double massLoad;

    // --- return if there is no area or no pollutants
    if ( Nobjects[POLLUT] == 0 || Subcatch[j].area == 0.0 ) return;

    // --- intialize outflow loads to zero
    for (p = 0; p < Nobjects[POLLUT]; p++)
    {
        WashoffLoad[p] = 0.0;      // load just from washoff function
        OutflowLoad[p] = 0.0;      // Washoff load + ponded water load
    }

    // --- add outflow of pollutants in ponded water to outflow loads
    //     (Note: at this point, Subcatch.newQual contains mass inflow
    //      from any upstream subcatchments draining to this one)
    updatePondedQual(j, Subcatch[j].newQual, Subcatch[j].pondedQual, tStep);

    // --- add washoff loads from landuses to outflow loads
    if ( runoff >= MIN_RUNOFF )
    {
        for (i = 0; i < Nobjects[LANDUSE]; i++)
        {
            if ( Subcatch[j].landFactor[i].fraction > 0.0 )
            {
                landuse_getWashoff(i, Subcatch[j].area, Subcatch[j].landFactor,
                                   runoff, tStep, WashoffLoad);
            }
        }

        // --- compute contribution from any co-pollutant
        for (p = 0; p < Nobjects[POLLUT]; p++)
        {
            WashoffLoad[p] += landuse_getCoPollutLoad(p, WashoffLoad);
            OutflowLoad[p] += WashoffLoad[p];
        }

    }

    // --- switch from internal runoff (used in washoff functions) to
    //     runoff that actually leaves the subcatchment
    runoff = Subcatch[j].newRunoff;

    // --- for each pollutant
    for (p = 0; p < Nobjects[POLLUT]; p++)
    {
        // --- update subcatchment's total runoff load in lbs (or kg)
        massLoad = OutflowLoad[p] * Pollut[p].mcf;
        Subcatch[j].totalLoad[p] += massLoad;

        // --- update overall runoff mass balance if runoff goes to
        //     conveyance system
        if ( Subcatch[j].outNode >= 0 || Subcatch[j].outSubcatch == j )
            massbal_updateLoadingTotals(RUNOFF_LOAD, p, massLoad);

        // --- save new outflow runoff concentration (in mass/L)
        if ( runoff > MIN_RUNOFF )
            Subcatch[j].newQual[p] = OutflowLoad[p] / (runoff * tStep * LperFT3);
        else Subcatch[j].newQual[p] = 0.0;
    }
}