Showing posts with label LID. Show all posts
Showing posts with label LID. Show all posts

Tuesday, March 21, 2023

InfoSWMM LIDCTRL.DBF File in ISDB Folder

 InfoSWMM LIDCTRL.DBF File in ISDB Folder, LID Data


IDAA
DESCRIPT
TYPE
SF_STORDEP
SF_VGCOVER
SF_SFROUGH
SF_SFSLOPE
SF_SDSLOPE
SO_THICK
SO_POROS
SO_FLDCAP
SO_WILTPT
SO_CNDT
SO_CNDTSL
SO_SUCTHD
SL_HEIGHT
SL_VRATIO
SL_CNDT
SL_CLOGFA
PV_THICK
PV_VRATIO
PV_IMPSFF
PV_PERMEAB
PV_CLOGFA
UD_DRNCOEF
UD_DRNEXPN
UD_DRNOFFH
UD_DRNDLY
DM_THICK
DM_VRATIO
DM_ROUGH
PV_REGEN_T
PV_REGEN_D
UD_H_OPEN
UD_H_CLOSE
UD_Q_CURVE

I

Sunday, January 22, 2023

SWMM 5.2.2 LID code for readSurfaceData

This code reads data for a specific LID process from a line of an input file, and assigns the data to variables in an array called "LidProcs". The data includes values for storage height, vegetation volume fraction, roughness, surface slope, and side slope. The code first checks if there are enough tokens in the input file, and then uses a loop to check if each token is a valid number and is greater than or equal to 0. If any of these conditions are not met, an error code is returned. The code then assigns the data to the appropriate variables in the LidProcs array, after converting the units and making sure that some values are set to 0 if other values meet certain conditions. The code returns 0 if there is no error.

int readSurfaceData(int j, char* toks[], int ntoks)
//
//  Purpose: reads surface layer data for a LID process from line of input
//           data file
//  Input:   j = LID process index 
//           toks = array of string tokens
//           ntoks = number of tokens
//  Output:  returns error code
//
//  Format of data is:
//  LID_ID  SURFACE  StorageHt  VegVolFrac  Roughness  SurfSlope  SideSlope
//
{
    int    i;
    double x[5];

    if ( ntoks < 7 ) return error_setInpError(ERR_ITEMS, "");
    for (i = 2; i < 7; i++)
    {
        if ( ! getDouble(toks[i], &x[i-2]) || x[i-2] < 0.0 )
            return error_setInpError(ERR_NUMBER, toks[i]);
    }
    if ( x[1] >= 1.0 ) return error_setInpError(ERR_NUMBER, toks[3]);           
    if ( x[0] == 0.0 ) x[1] = 0.0;

    LidProcs[j].surface.thickness     = x[0] / UCF(RAINDEPTH);
    LidProcs[j].surface.voidFrac      = 1.0 - x[1];
    LidProcs[j].surface.roughness     = x[2];
    LidProcs[j].surface.surfSlope     = x[3] / 100.0;
    LidProcs[j].surface.sideSlope     = x[4];
    return 0;
}

Saturday, January 21, 2023

SWMM 5.2.2 Code for LID Function lidproc_getOutflow

 This code is part of a function called "lidproc_getOutflow" that computes the runoff outflow from a single LID (Low Impact Development) unit.

The function takes in multiple inputs: a pointer to a specific LID unit, a pointer to a generic LID process, the runoff rate captured by the LID unit, potential evaporation rate, infiltration rate to native soil, maximum infiltration rate to native soil, and time step. It returns surface runoff rate from the LID unit, and sets the values of lidEvap, lidInfil, and lidDrain.

The function uses several arrays and variables to store values such as layer moisture levels, previously and newly computed flux rates, and layer moisture limits. It also defines a pointer to a function that computes flux rates through the LID. It initializes various values such as layer moisture volumes, flux rates, and moisture limits. Then it finds Green-Ampt infiltration from the surface layer and calls the appropriate flux rate function for the LID type.

Input VariablesTypeDescriptionUnits
lidUnitpointerPointer to specific LID unit being analyzed
lidProcpointerPointer to generic LID process of the LID unit
inflowdoubleRunoff rate captured by LID unitft/s
evapdoublePotential evaporation rateft/s
infildoubleInfiltration rate to native soilft/s
maxInfildoubleMaximum infiltration rate to native soilft/s
tStepdoubleTime stepsec
Output VariablesTypeDescriptionUnits
lidEvapdouble pointerEvaporation rate for LID unitft/s
lidInfildouble pointerInfiltration rate for LID unitft/s
lidDraindouble pointerDrain flow for LID unitft/s
returnsdoubleSurface runoff rate from the LID unitft/s

Note: The table only contains the input/output variables defined in the function signature and the purpose of the function.

double lidproc_getOutflow(TLidUnit* lidUnit, TLidProc* lidProc, double inflow,
                          double evap, double infil, double maxInfil,
                          double tStep, double* lidEvap,
                          double* lidInfil, double* lidDrain)
//
//  Purpose: computes runoff outflow from a single LID unit.
//  Input:   lidUnit  = ptr. to specific LID unit being analyzed
//           lidProc  = ptr. to generic LID process of the LID unit
//           inflow   = runoff rate captured by LID unit (ft/s)
//           evap     = potential evaporation rate (ft/s)
//           infil    = infiltration rate to 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)
//           lidDrain = drain flow for LID unit (ft/s)
//           returns surface runoff rate from the LID unit (ft/s)
//
{
    int    i;
    double x[MAX_LAYERS];        // layer moisture levels
    double xOld[MAX_LAYERS];     // work vector
    double xPrev[MAX_LAYERS];    // work vector
    double xMin[MAX_LAYERS];     // lower limit on moisture levels
    double xMax[MAX_LAYERS];     // upper limit on moisture levels
    double fOld[MAX_LAYERS];     // previously computed flux rates
    double f[MAX_LAYERS];        // newly computed flux rates

    // convergence tolerance on moisture levels (ft, moisture fraction , ft)
    double xTol[MAX_LAYERS] = {STOPTOL, STOPTOL, STOPTOL, STOPTOL};

    double omega = 0.0;          // integration time weighting

    //... 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 evap, max. infil. & time step to shared variables
    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;
    x[PAVE] = theLidUnit->paveDepth;

    //... initialize layer moisture volumes, flux rates and moisture limits
    SurfaceVolume  = 0.0;
    PaveVolume     = 0.0;
    SoilVolume     = 0.0;
    StorageVolume  = 0.0;
    SurfaceInflow  = inflow;
    SurfaceInfil   = 0.0;
    SurfaceEvap    = 0.0;
    SurfaceOutflow = 0.0;
    PaveEvap       = 0.0;
    PavePerc       = 0.0;
    SoilEvap       = 0.0;
    SoilPerc       = 0.0;
    StorageInflow  = 0.0;
    StorageExfil   = 0.0;
    StorageEvap    = 0.0;
    StorageDrain   = 0.0;
    for (i = 0; i < MAX_LAYERS; 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 ( theLidProc->lidType == POROUS_PAVEMENT ) SurfaceInfil = 0.0;
    else if ( theLidUnit->soilInfil.Ks > 0.0 )
    {
        SurfaceInfil =
            grnampt_getInfil(&theLidUnit->soilInfil, Tstep,
                             SurfaceInflow, theLidUnit->surfaceDepth,
                             MOD_GREEN_AMPT);
    }
    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[PAVE] = theLidProc->pavement.thickness;
    }
    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 ROOF_DISCON:     fluxRates = &roofFluxRates;      break;
    case VEG_SWALE:       fluxRates = &swaleFluxRates;
                          omega = 0.5;
                          break;
    default:              return 0.0;
    }

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

/** 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->paveDepth    = x[PAVE];
    theLidUnit->soilMoisture = x[SOIL];
    theLidUnit->storageDepth = x[STOR];
    for (i = 0; i < MAX_LAYERS; i++) theLidUnit->oldFluxRates[i] = f[i];

    //... assign values to LID unit evaporation, infiltration & drain flow
    *lidEvap = SurfaceEvap + PaveEvap + SoilEvap + StorageEvap;
    *lidInfil = StorageExfil;
    *lidDrain = StorageDrain;

    //... return surface outflow (per unit area) from unit
    return SurfaceOutflow;
}

AI Rivers of Wisdom about ICM SWMM

Here's the text "Rivers of Wisdom" formatted with one sentence per line: [Verse 1] 🌊 Beneath the ancient oak, where shadows p...