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 Variables | Type | Description | Units |
---|
lidUnit | pointer | Pointer to specific LID unit being analyzed | |
lidProc | pointer | Pointer to generic LID process of the LID unit | |
inflow | double | Runoff rate captured by LID unit | ft/s |
evap | double | Potential evaporation rate | ft/s |
infil | double | Infiltration rate to native soil | ft/s |
maxInfil | double | Maximum infiltration rate to native soil | ft/s |
tStep | double | Time step | sec |
Output Variables | Type | Description | Units |
---|
lidEvap | double pointer | Evaporation rate for LID unit | ft/s |
lidInfil | double pointer | Infiltration rate for LID unit | ft/s |
lidDrain | double pointer | Drain flow for LID unit | ft/s |
returns | double | Surface runoff rate from the LID unit | ft/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;
}