예제 #1
0
파일: exfil.c 프로젝트: lothar-mar/swmm5
double exfil_getLoss(TExfil* exfil, double tStep, double depth, double area)
//
//  Input:   exfil = ptr. to a storage exfiltration object
//           tStep = time step (sec)
//           depth = water depth (ft)
//           area = surface area (ft2)
//  Output:  returns exfiltration rate out of storage unit (cfs)
//  Purpose: computes rate of water exfiltrated from a storage node into
//           the soil beneath it.
//
{
    double exfilRate = 0.0;

    // --- find infiltration through bottom of unit
    if ( exfil->btmExfil->IMDmax == 0.0 )
    {
        exfilRate = exfil->btmExfil->Ks * Adjust.hydconFactor;                 //(5.1.008)
    }
    else exfilRate = grnampt_getInfil(exfil->btmExfil, tStep, 0.0, depth);
    exfilRate *= exfil->btmArea;

    // --- find infiltration through sloped banks
    if ( depth > exfil->bankMinDepth )
    {
        // --- get area of banks
        area = MIN(area, exfil->bankMaxArea) - exfil->btmArea;
        if ( area > 0.0 )
        {
            // --- if infil. rate not a function of depth
            if ( exfil->btmExfil->IMDmax == 0.0 )
            {    
                exfilRate += area * exfil->btmExfil->Ks * Adjust.hydconFactor; //(5.1.008)
            }

            // --- infil. rate depends on depth above bank
            else
            {
                // --- case where water depth is above the point where the
                //     storage curve no longer has increasing area with depth
                if ( depth > exfil->bankMaxDepth )
                {
                    depth = depth - exfil->bankMaxDepth +
                               (exfil->bankMaxDepth - exfil->bankMinDepth) / 2.0;
                }

                // --- case where water depth is below top of bank
                else depth = (depth - exfil->bankMinDepth) / 2.0;

                // --- use Green-Ampt function for bank infiltration
                exfilRate += area * grnampt_getInfil(exfil->bankExfil,
                                    tStep, 0.0, depth);
            }
        }
    }
    return exfilRate;
}
예제 #2
0
double infil_getInfil(int j, int m, double tstep, double rainfall,
                      double runon, double depth)
//
//  Input:   j = subcatchment index
//           m = infiltration method code
//           tstep = runoff time step (sec)
//           rainfall = rainfall rate (ft/sec)
//           runon = runon rate from other sub-areas or subcatchments (ft/sec)
//           depth = depth of surface water on subcatchment (ft)
//  Output:  returns infiltration rate (ft/sec)
//  Purpose: computes infiltration rate depending on infiltration method.
//
{
    switch (m)
    {
      case HORTON:
          return horton_getInfil(&HortInfil[j], tstep, rainfall+runon, depth);

      case MOD_HORTON:
          return modHorton_getInfil(&HortInfil[j], tstep, rainfall+runon,
                                    depth);

      case GREEN_AMPT:
      case MOD_GREEN_AMPT:                                                     //(5.1.010)
        return grnampt_getInfil(&GAInfil[j], tstep, rainfall+runon, depth, m); //(5.1.010)

      case CURVE_NUMBER:
        depth += runon / tstep;
        return curvenum_getInfil(&CNInfil[j], tstep, rainfall, depth);

      default:
        return 0.0;
    }
}
예제 #3
0
파일: lidproc.c 프로젝트: ezhangle/swmm
double lidproc_getOutflow(TLidUnit* lidUnit, TLidProc* lidProc, double inflow,
                          double rain, double evap, double infil,
                          double maxInfil, double tStep, double* lidEvap,
                          double* lidInfil)
//
//  Purpose: computes runoff outflow from a single LID unit.
//  Input:   theUnit  = ptr. to specific LID unit being analyzed
//           theProc  = ptr. to generic LID process of the LID unit
//           inflow   = runoff rate captured by LID unit (ft/s)
//           rain     = current rainfall on LID unit (ft/s)
//           evap     = potential evaporation rate (ft/s)
//           infil    = infiltration rate of native soil (ft/s)
//           maxInfil = max. infiltration rate to native soil (ft/s)
//           tStep    = time step (sec)
//  Output:  lidEvap  = evaporation rate for LID unit (ft/s)
//           lidInfil = infiltration rate for LID unit (ft/s)
//           returns surface runoff rate from the LID unit (ft/s)
//
{
    int    i;
    double x[MAX_STATE_VARS];        // layer moisture levels
    double xOld[MAX_STATE_VARS];     // work vector 
    double xPrev[MAX_STATE_VARS];    // work vector
    double xMin[MAX_STATE_VARS];     // lower limit on moisture levels
    double xMax[MAX_STATE_VARS];     // upper limit on moisture levels
    double fOld[MAX_STATE_VARS];     // previously computed flux rates
    double f[MAX_STATE_VARS];        // newly computed flux rates
    double xTol[] =                  // convergence tolerance on moisture
        {STOPTOL, STOPTOL, STOPTOL}; // levels (ft, moisture fraction , ft)
    double omega = 0.0;              // integration time weighting             //(5.1.007)

    //... define a pointer to function that computes flux rates through the LID
    void (*fluxRates) (double *, double *) = NULL;

    //... save references to the LID process and LID unit
    theLidProc = lidProc;
    theLidUnit = lidUnit;

    //... save rain, evap, max. infil. & time step to shared variables
    Rainfall = rain;
    EvapRate = evap;
    MaxNativeInfil = maxInfil;
    Tstep = tStep;

    //... store current moisture levels in vector x
    x[SURF] = theLidUnit->surfaceDepth;
    x[SOIL] = theLidUnit->soilMoisture;
    x[STOR] = theLidUnit->storageDepth;

    //... initialize layer flux rates and moisture limits
    SurfaceInflow  = inflow;
    SurfaceInfil   = 0.0;
    SurfaceEvap    = 0.0;
    SurfaceOutflow = 0.0;
    SoilEvap       = 0.0;
    SoilPerc       = 0.0;
    StorageInflow  = 0.0;
    StorageInfil   = 0.0;
    StorageEvap    = 0.0;
    StorageDrain   = 0.0;
    for (i = 0; i < MAX_STATE_VARS; i++)
    {
        f[i] = 0.0;
        fOld[i] = theLidUnit->oldFluxRates[i];
        xMin[i] = 0.0;
        xMax[i] = BIG;
        Xold[i] = x[i];
    }

    //... find Green-Ampt infiltration from surface layer
    if ( theLidUnit->soilInfil.Ks > 0.0 )
    {
        SurfaceInfil =
            grnampt_getInfil(&theLidUnit->soilInfil, Tstep,
                             SurfaceInflow, theLidUnit->surfaceDepth);
    }
    else SurfaceInfil = infil;

    //... set moisture limits for soil & storage layers
    if ( theLidProc->soil.thickness > 0.0 )
    {
        xMin[SOIL] = theLidProc->soil.wiltPoint;
        xMax[SOIL] = theLidProc->soil.porosity;
    }
    if ( theLidProc->pavement.thickness > 0.0 )
    {
        xMax[SOIL] = theLidProc->pavement.voidFrac;
    }
    if ( theLidProc->storage.thickness > 0.0 )
    {
        xMax[STOR] = theLidProc->storage.thickness;
    }
    if ( theLidProc->lidType == GREEN_ROOF )
    {
        xMax[STOR] = theLidProc->drainMat.thickness;
    }

    //... determine which flux rate function to use
    switch (theLidProc->lidType)
    {
    case BIO_CELL:
    case RAIN_GARDEN:     fluxRates = &biocellFluxRates;  break;
    case GREEN_ROOF:      fluxRates = &greenRoofFluxRates; break;
    case INFIL_TRENCH:    fluxRates = &trenchFluxRates;   break;
    case POROUS_PAVEMENT: fluxRates = &pavementFluxRates; break;
    case RAIN_BARREL:     fluxRates = &barrelFluxRates;   break;
    case VEG_SWALE:       fluxRates = &swaleFluxRates;
                          omega = 0.5;                                         //(5.1.007)
                          break;
    default:              return 0.0;
    }

    //... update moisture levels and flux rates over the time step
    i = modpuls_solve(MAX_STATE_VARS, x, xOld, xPrev, xMin, xMax, xTol,
                     fOld, f, tStep, omega, fluxRates);                        //(5.1.007)

/** For debugging only ********************************************
    if  (i == 0) 
    {
        fprintf(Frpt.file,
        "\n  WARNING 09: integration failed to converge at %s %s",
            theDate, theTime);
        fprintf(Frpt.file,
        "\n              for LID %s placed in subcatchment %s.",
            theLidProc->ID, theSubcatch->ID);
    }
*******************************************************************/

    //... add any surface overflow to surface outflow
    if ( theLidProc->surface.canOverflow || theLidUnit->fullWidth == 0.0 )
    {
        SurfaceOutflow += getSurfaceOverflowRate(&x[SURF]);
    }

    //... save updated results
    theLidUnit->surfaceDepth = x[SURF];
    theLidUnit->soilMoisture = x[SOIL];
    theLidUnit->storageDepth = x[STOR];
    for (i = 0; i < MAX_STATE_VARS; i++) theLidUnit->oldFluxRates[i] = f[i];

    //... assign values to LID unit evaporation & infiltration
    *lidEvap = SurfaceEvap + SoilEvap + StorageEvap;
    *lidInfil = StorageInfil;

    //... return total outflow (per unit area) from unit
    return SurfaceOutflow + StorageDrain;
}    
예제 #4
0
파일: node.c 프로젝트: iut-ibk/DynaVIBe
double storage_getLosses(int j, double tStep)
//
//  Input:   j = node index
//           tStep = time step (sec)
//  Output:  returns volume of water evaporated & infiltrated (ft3)
//  Purpose: computes volume of water evaporated & infiltrated from a storage
//           node over a given time step.
//
{
    double depth;
    double area = 0.0;
    double area0 = 0.0;
    double evapRate;
    double evapLoss = 0.0;
    double infilLoss = 0.0;
    double totalLoss = 0.0;
    double maxLoss;
    TGrnAmpt* infil;

    // --- adjust evaporation rate for storage unit's evaporation potential
    evapRate = Evap.rate * Storage[Node[j].subIndex].fEvap;
    if ( evapRate > 0.0 )
    {
        // --- find surface area available for evaporation
        depth = Node[j].oldDepth;
        if ( depth > FUDGE ) area += storage_getSurfArea(j, depth);
        depth = Node[j].newDepth;
        if ( depth > FUDGE ) area += storage_getSurfArea(j, depth);

        // --- compute evaporation loss over average area
        evapLoss = 0.5 * area * evapRate * tStep;
    }

    // --- compute infiltration loss
    infil = Storage[Node[j].subIndex].infil;
    if (infil)
    {
        // --- find average depth over time step
        depth = 0.5 * (Node[j].oldDepth + Node[j].newDepth);

        // --- get surface area at avg. depth and at bottom of unit
        area0 = storage_getSurfArea(j, 0.0);
        area = area0;
        if ( depth > FUDGE ) area = storage_getSurfArea(j, depth);
        if ( area > 0.0 )
        {
            // --- get average depth assuming sloped sides
            depth = depth / 2.0 * (1.0 + area0/area);

            // --- compute infil. loss considering ponded depth
            infilLoss = grnampt_getInfil(infil, tStep, 0.0, depth) *
                        area * tStep;
        }
    }

    // --- compute total loss
    totalLoss = evapLoss + infilLoss;
    maxLoss = 0.5 * (Node[j].oldVolume + Node[j].newVolume);
    if ( totalLoss > 0.0 )
    {
        if ( totalLoss > maxLoss )
        {
            evapLoss = (evapLoss / totalLoss) * maxLoss;
            totalLoss = maxLoss;
        }
    }
    Storage[Node[j].subIndex].evapLoss = evapLoss;
    Storage[Node[j].subIndex].losses = totalLoss;
    return totalLoss;
}