Saturday, January 21, 2023

SWMM 5.2.2 Code for LID Function greenRoofFluxRates

This code is a function called "greenRoofFluxRates" that calculates flux rates from the layers of a green roof. It takes in two input arrays, "x" and "f", which represent the vector of storage levels and the vector of flux rates, respectively. The function uses several intermediate variables, including "availVolume" and "maxRate". It also makes use of several properties of the green roof, such as "soilThickness", "storageThickness", "soilPorosity", "storageVoidFrac", "soilFieldCap", and "soilWiltPoint".

The code first retrieves the moisture levels from the input vector "x" and converts them to volumes. It then calculates the ET rates, soil layer perc rate, and storage (drain mat) outflow rate. The code also checks for the case where the unit is full and limits the rates accordingly. The Surface infil is adjusted so that the soil porosity is not exceeded. The code also finds the surface outflow rate and computes overall layer flux rates.

A table of the variables used in this function and their descriptions is as follows:

Variable NameDescription
x[SURF], x[SOIL], x[STOR]Input vector of storage levels
f[SURF], f[SOIL], f[STOR]Output vector of flux rates
surfaceDepthMoisture level variable for the surface layer
soilThetaMoisture level variable for the soil layer
storageDepthMoisture level variable for the storage layer
availVolumeIntermediate variable for available volume
maxRateIntermediate variable for maximum rate
soilThicknessProperty of the soil layer representing its thickness
storageThicknessProperty of the storage layer representing its thickness
soilPorosityProperty of the soil layer representing its porosity

Variable NameDescription
storageVoidFracProperty of the storage layer representing its void fraction
soilFieldCapProperty of the soil layer representing its field capacity
soilWiltPointProperty of the soil layer representing its wilting point
SurfaceVolumeVolume of the surface layer
SoilVolumeVolume of the soil layer
StorageVolumeVolume of the storage layer
SurfaceInflowInflow rate to the surface layer
SurfaceEvapEvaporation rate from the surface layer
SoilPercPercolation rate out of the soil layer
SoilEvapEvaporation rate from the soil layer
StorageExfilExfiltration rate out of the storage layer
StorageDrainDrain flow rate out of the storage layer
SurfaceInfilInfiltration rate into the soil layer
SurfaceOutflowOutflow rate from the surface layer

The code uses several helper functions:

  • getEvapRates(SurfaceVolume, 0.0, availVolume, StorageVolume, 1.0) : to calculate evaporation rate
  • getSoilPercRate(soilTheta) : to calculate soil percolation rate
  • getDrainMatOutflow(storageDepth) : to calculate storage (drain mat) outflow rate
  • getSurfaceOutflowRate(surfaceDepth) : to calculate surface outflow rate

The final output of the function is the overall flux rate for each of the three layers: surface, soil, and storage.


void greenRoofFluxRates(double x[], double f[])
//
//  Purpose: computes flux rates from the layers of a green roof.
//  Input:   x = vector of storage levels
//  Output:  f = vector of flux rates
//
{
    // Moisture level variables
    double surfaceDepth;
    double soilTheta;
    double storageDepth;

    // Intermediate variables
    double availVolume;
    double maxRate;

    // Green roof properties
    double soilThickness    = theLidProc->soil.thickness;
    double storageThickness = theLidProc->storage.thickness;
    double soilPorosity     = theLidProc->soil.porosity;
    double storageVoidFrac  = theLidProc->storage.voidFrac;
    double soilFieldCap     = theLidProc->soil.fieldCap;
    double soilWiltPoint    = theLidProc->soil.wiltPoint;

    //... retrieve moisture levels from input vector
    surfaceDepth = x[SURF];
    soilTheta    = x[SOIL];
    storageDepth = x[STOR];

    //... convert moisture levels to volumes
    SurfaceVolume = surfaceDepth * theLidProc->surface.voidFrac;
    SoilVolume = soilTheta * soilThickness;
    StorageVolume = storageDepth * storageVoidFrac;

    //... get ET rates
    availVolume = SoilVolume - soilWiltPoint * soilThickness;
    getEvapRates(SurfaceVolume, 0.0, availVolume, StorageVolume, 1.0);
    if ( soilTheta >= soilPorosity ) StorageEvap = 0.0;

    //... soil layer perc rate
    SoilPerc = getSoilPercRate(soilTheta);

    //... limit perc rate by available water
    availVolume = (soilTheta - soilFieldCap) * soilThickness;
    maxRate = MAX(availVolume, 0.0) / Tstep - SoilEvap;
    SoilPerc = MIN(SoilPerc, maxRate);
    SoilPerc = MAX(SoilPerc, 0.0);

    //... storage (drain mat) outflow rate
    StorageExfil = 0.0;
    StorageDrain = getDrainMatOutflow(storageDepth);

    //... unit is full
    if ( soilTheta >= soilPorosity && storageDepth >= storageThickness )
    {
        //... outflow from both layers equals limiting rate
        maxRate = MIN(SoilPerc, StorageDrain);
        SoilPerc = maxRate;
        StorageDrain = maxRate;

        //... adjust inflow rate to soil layer
        SurfaceInfil = MIN(SurfaceInfil, maxRate);
    }

    //... unit not full
    else
    {
        //... limit drainmat outflow by available storage volume
        maxRate = storageDepth * storageVoidFrac / Tstep - StorageEvap;
        if ( storageDepth >= storageThickness ) maxRate += SoilPerc;
        maxRate = MAX(maxRate, 0.0);
        StorageDrain = MIN(StorageDrain, maxRate);

        //... limit soil perc inflow by unused storage volume
        maxRate = (storageThickness - storageDepth) * storageVoidFrac / Tstep +
                  StorageDrain + StorageEvap;
        SoilPerc = MIN(SoilPerc, maxRate);
                
        //... adjust surface infil. so soil porosity not exceeded
        maxRate = (soilPorosity - soilTheta) * soilThickness / Tstep +
                  SoilPerc + SoilEvap;
        SurfaceInfil = MIN(SurfaceInfil, maxRate);
    }

    // ... find surface outflow rate
    SurfaceOutflow = getSurfaceOutflowRate(surfaceDepth);

    // ... compute overall layer flux rates
    f[SURF] = (SurfaceInflow - SurfaceEvap - SurfaceInfil - SurfaceOutflow) /
              theLidProc->surface.voidFrac;
    f[SOIL] = (SurfaceInfil - SoilEvap - SoilPerc) /
              theLidProc->soil.thickness;
    f[STOR] = (SoilPerc - StorageEvap - StorageDrain) /
              theLidProc->storage.voidFrac;
}

No comments:

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...