Пример #1
0
void  getFluxes(double theta, double lowerDepth)
//
//  Input:   upperVolume = vol. depth of upper zone (ft)
//           upperDepth  = depth of upper zone (ft)
//  Output:  none
//  Purpose: computes water fluxes into/out of upper/lower GW zones.
//
{
    double upperDepth;

    // --- find upper zone depth
    lowerDepth = MAX(lowerDepth, 0.0);
    lowerDepth = MIN(lowerDepth, TotalDepth);
    upperDepth = TotalDepth - lowerDepth;

    // --- find evaporation from both zones
    getEvapRates(theta, upperDepth);

    // --- find percolation rate at upper & lower zone boundaries
    UpperPerc = getUpperPerc(theta, upperDepth);
    UpperPerc = MIN(UpperPerc, MaxUpperPerc);

    // --- find losses to deep GW
    LowerLoss = A.lowerLossCoeff * lowerDepth / TotalDepth;

    // --- find GW flow from lower zone to conveyance system node
    GWFlow = getGWFlow(lowerDepth);
    if ( GWFlow >= 0.0 ) GWFlow = MIN(GWFlow, MaxGWFlowPos);
    else GWFlow = MAX(GWFlow, MaxGWFlowNeg);
}
Пример #2
0
void  getFluxes(Project* project, double theta, double lowerDepth)
//
//  Input:   upperVolume = vol. depth of upper zone (ft)
//           upperDepth  = depth of upper zone (ft)
//  Output:  none
//  Purpose: computes water fluxes into/out of upper/lower project->GW zones.
//
{
    double upperDepth;

    // --- find upper zone depth
    lowerDepth = MAX(lowerDepth, 0.0);
    lowerDepth = MIN(lowerDepth, project->TotalDepth);
    upperDepth = project->TotalDepth - lowerDepth;

    // --- save lower depth and theta to global variables
    project->Hgw = lowerDepth;
    project->Theta = theta;

    // --- find evaporation rate from both zones
    getEvapRates(project,theta, upperDepth);

    // --- find percolation rate from upper to lower zone
    project->UpperPerc = getUpperPerc(project,theta, upperDepth);
    project->UpperPerc = MIN(project->UpperPerc, project->MaxUpperPerc);

    // --- find loss rate to deep project->GW
    if ( project->DeepFlowExpr != NULL )
        project->LowerLoss = mathexpr_eval(project, project->DeepFlowExpr, getVariableValue) /
                    UCF(project,RAINFALL);
    else
        project->LowerLoss = project->A.lowerLossCoeff * lowerDepth / project->TotalDepth;
    project->LowerLoss = MIN(project->LowerLoss, lowerDepth/project->Tstep);

    // --- find project->GW flow rate from lower zone to drainage system node
    project->GWFlow = getGWFlow(project,lowerDepth);
    if ( project->LatFlowExpr != NULL )
    {
		project->GWFlow += mathexpr_eval(project, project->LatFlowExpr, getVariableValue) / UCF(project, GWFLOW);
    }
    if ( project->GWFlow >= 0.0 ) project->GWFlow = MIN(project->GWFlow, project->MaxGWFlowPos);
    else project->GWFlow = MAX(project->GWFlow, project->MaxGWFlowNeg);
}
void  getFluxes(double theta, double lowerDepth)
//
//  Input:   upperVolume = vol. depth of upper zone (ft)
//           upperDepth  = depth of upper zone (ft)
//  Output:  none
//  Purpose: computes water fluxes into/out of upper/lower GW zones.
//
{
    double upperDepth;

    // --- find upper zone depth
    lowerDepth = MAX(lowerDepth, 0.0);
    lowerDepth = MIN(lowerDepth, TotalDepth);
    upperDepth = TotalDepth - lowerDepth;

    // --- save lower depth and theta to global variables
    Hgw = lowerDepth;
    Theta = theta;

    // --- find evaporation rate from both zones
    getEvapRates(theta, upperDepth);

    // --- find percolation rate from upper to lower zone
    UpperPerc = getUpperPerc(theta, upperDepth);
    UpperPerc = MIN(UpperPerc, MaxUpperPerc);

    // --- find loss rate to deep GW
    if ( DeepFlowExpr != NULL )
        LowerLoss = mathexpr_eval(DeepFlowExpr, getVariableValue) /
                    UCF(RAINFALL);
    else
        LowerLoss = A.lowerLossCoeff * lowerDepth / TotalDepth;
    LowerLoss = MIN(LowerLoss, lowerDepth/Tstep);

    // --- find GW flow rate from lower zone to drainage system node
    GWFlow = getGWFlow(lowerDepth);
    if ( LatFlowExpr != NULL )
    {
        GWFlow += mathexpr_eval(LatFlowExpr, getVariableValue) / UCF(GWFLOW);
    }
    if ( GWFlow >= 0.0 ) GWFlow = MIN(GWFlow, MaxGWFlowPos);
    else GWFlow = MAX(GWFlow, MaxGWFlowNeg);
}
Пример #4
0
void pavementFluxRates(double x[], double f[])
//
//  Purpose: computes flux rates from the layers of a porous pavement LID.
//  Input:   x = vector of storage levels
//  Output:  f = vector of flux rates
//
{
    double surfaceDepth;     // depth of water stored on surface (ft)
    double paveTheta;        // moisture content of pavement voids
    double storageDepth;     // depth of water in storage layer (ft)
    double pervVolume;       // volume/unit area of pervious pavement (ft)
    double pavePorosity;     // pavement porosity
    double availVolume;
    double maxRate;
    double head;

    //... retrieve state variables from work vector
    surfaceDepth = x[SURF];
    paveTheta = x[SOIL];
    storageDepth = x[STOR];
    pavePorosity = theLidProc->pavement.voidFrac;

    //... convert state variables to volumes
    //    (SoilVolume refers to pavement layer)
    SurfaceVolume = surfaceDepth * theLidProc->surface.voidFrac;
    pervVolume = theLidProc->pavement.thickness *
                 (1.0 - theLidProc->pavement.impervFrac);
    SoilVolume = paveTheta * pervVolume;
    StorageVolume = storageDepth * theLidProc->storage.voidFrac;

    //... get ET rates (arguments are stored volumes in ft)
    getEvapRates(SurfaceVolume, SoilVolume, StorageVolume);

    //... no storage evap if pavement layer saturated
    if ( paveTheta >= pavePorosity ) StorageEvap = 0.0;

    //... find nominal rate of surface infiltration into pavement
    SurfaceInfil = SurfaceInflow + (SurfaceVolume / Tstep);

    //... find pavement layer permeability (referred to as SoilPerc)
    SoilPerc = getPavementPermRate();

    //... limit pavement permeability to stored water + surface infil.
    maxRate = SoilVolume/Tstep + SurfaceInfil;
    SoilPerc = MIN(SoilPerc, maxRate);

    //... find infiltration rate out of storage layer
    StorageInfil = getStorageInfilRate();

    //... find underdrain flow rate
    StorageDrain = 0.0;
    head = storageDepth - theLidProc->drain.offset;
    if ( theLidProc->drain.coeff > 0.0 && head >= 0.0 )
    {
        if ( storageDepth >= theLidProc->storage.thickness )
        {
            head += (paveTheta) / pavePorosity * theLidProc->pavement.thickness;
            if ( paveTheta >= pavePorosity ) head += surfaceDepth;
        }
        StorageDrain =  getStorageDrainRate(head);
    }

    //... unit is flooded
    if ( storageDepth >= theLidProc->storage.thickness &&
        paveTheta >= pavePorosity && SurfaceInfil > MIN_RUNOFF )
    {
        //... pavement outflow can't exceed surface infil
        SoilPerc = MIN(SurfaceInfil, SoilPerc);

        //... pavement outflow can't exceed storage outflow
        maxRate = StorageEvap + StorageDrain + StorageInfil;
        if ( SoilPerc > maxRate )
        {
            SoilPerc = maxRate;
            SurfaceInfil = SoilPerc;
        }

        //... storage outflow can't exceed pavement perm.
        else
        {
            StorageDrain = MIN(StorageDrain, SoilPerc);
            StorageInfil = SoilPerc - StorageDrain;
        }
    }

    //... unit not flooded
    else
    {
        //... limit underdrain flow by volume above drain offset
        if ( StorageDrain > 0.0 )
        {
            maxRate = (storageDepth - theLidProc->drain.offset) *
                      theLidProc->storage.voidFrac / Tstep;
            StorageDrain = MIN(StorageDrain, maxRate);
        }

        //... limit storage infil. by remaining volume
        maxRate = StorageVolume / Tstep - StorageDrain - StorageEvap;
        maxRate = MAX(0.0, maxRate);
        StorageInfil = MIN(StorageInfil, maxRate);

        //... limit pavement outflow by available storage volume
        availVolume = (theLidProc->storage.thickness - storageDepth) *
            theLidProc->storage.voidFrac;
        maxRate = availVolume/Tstep + StorageEvap + StorageDrain + StorageInfil;
        maxRate = MAX(maxRate, 0.0);
        SoilPerc = MIN(SoilPerc, maxRate);

        //... limit pavement inflow by available pavement volume
        availVolume = (pavePorosity - paveTheta) * pervVolume;
        maxRate = availVolume / Tstep + SoilPerc;
        SurfaceInfil = MIN(SurfaceInfil, maxRate);
    }

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

    //... compute overall layer flux rates
    f[SURF] = SurfaceInflow - SurfaceEvap - SurfaceInfil - SurfaceOutflow;
    f[SOIL] = (SurfaceInfil - SoilEvap - SoilPerc) / pervVolume;
    f[STOR] = (SoilPerc - StorageEvap - StorageInfil - StorageDrain) /
              theLidProc->storage.voidFrac;
}
Пример #5
0
void trenchFluxRates(double x[], double f[])
//
//  Purpose: computes flux rates from the layers of an infiltration trench LID.
//  Input:   x = vector of storage levels
//  Output:  f = vector of flux rates
//
{
    double surfaceDepth;
    double storageDepth;
    double head;
    double availVolume;
    double maxRate;

    //... extract zone depth levels from work vector
    surfaceDepth = x[SURF];
    storageDepth = x[STOR];

    //... convert depths to volumes
    SurfaceVolume = surfaceDepth * theLidProc->surface.voidFrac;
    SoilVolume = 0.0;
    StorageVolume = storageDepth * theLidProc->storage.voidFrac;
    availVolume = (theLidProc->storage.thickness - storageDepth) *
                  theLidProc->storage.voidFrac;

    //... nominal storage inflow
    StorageInflow = SurfaceInflow + SurfaceVolume / Tstep;

    //... get ET rate loss for each zone 
    getEvapRates(SurfaceVolume, 0.0, StorageVolume);

    //... no storage evap if surface ponded
    if ( surfaceDepth > 0.0 ) StorageEvap = 0.0;

    //... find infiltration rate out of storage layer
   StorageInfil = getStorageInfilRate();

    //... find underdrain flow rate
    StorageDrain = 0.0;
    head = storageDepth - theLidProc->drain.offset;
    if ( theLidProc->drain.coeff > 0.0 && head >= 0.0 )
    {
        if ( storageDepth >= theLidProc->storage.thickness )
        {
            head += surfaceDepth;
        }
        StorageDrain =  getStorageDrainRate(head);
    }

    //... limit underdrain flow by volume above drain offset
    if ( StorageDrain > 0.0 )
    {
        maxRate = (storageDepth - theLidProc->drain.offset) *
                  theLidProc->storage.voidFrac / Tstep;
        //... add on storage inflow if storage is full
        if ( storageDepth >= theLidProc->storage.thickness )
            maxRate += StorageInflow;
        StorageDrain = MIN(StorageDrain, maxRate);
    }

    //... limit storage infil. by remaining volume
    maxRate = StorageVolume / Tstep - StorageDrain - StorageEvap;
    maxRate = MAX(0.0, maxRate);
    StorageInfil = MIN(StorageInfil, maxRate);

    //... limit storage inflow by available storage volume
    availVolume = (theLidProc->storage.thickness - storageDepth) *
        theLidProc->storage.voidFrac;
    maxRate = availVolume/Tstep + StorageEvap + StorageDrain + StorageInfil;
    maxRate = MAX(maxRate, 0.0);
    StorageInflow = MIN(StorageInflow, maxRate);

    //... equate surface infil to storage inflow
    SurfaceInfil = StorageInflow;

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

    // ... find net fluxes for each layer
    f[SURF] = SurfaceInflow - SurfaceEvap - StorageInflow - SurfaceOutflow /
              theLidProc->surface.voidFrac;;
    f[STOR] = (StorageInflow - StorageEvap - StorageInfil - StorageDrain) /
              theLidProc->storage.voidFrac;
    f[SOIL] = 0.0;
}
Пример #6
0
void biocellFluxRates(double x[], double f[])
//
//  Purpose: computes flux rates from the layers of a bio-retention cell LID.
//  Input:   x = vector of storage levels
//  Output:  f = vector of flux rates
//
{
    double surfaceDepth;
    double soilTheta;
    double storageDepth;
    double head;
    double availVolume;
    double maxRate;

    //... retrieve state variables from work vector
    surfaceDepth = x[SURF];
    soilTheta = x[SOIL];
    storageDepth = x[STOR];

    //... convert state variables to volumes
    SurfaceVolume = surfaceDepth * theLidProc->surface.voidFrac;
    SoilVolume = soilTheta * theLidProc->soil.thickness;
    StorageVolume = storageDepth * theLidProc->storage.voidFrac;

    //... get ET rates
    availVolume = SoilVolume - theLidProc->soil.wiltPoint *
                   theLidProc->soil.thickness;
    getEvapRates(SurfaceVolume, availVolume, StorageVolume);

    //... no storage evap if soil layer saturated
    if ( soilTheta >= theLidProc->soil.porosity ) StorageEvap = 0.0;

    //... find soil layer perc rate
    SoilPerc = getSoilPercRate(soilTheta);
    
    //... find infiltration rate out of storage layer
    StorageInfil = getStorageInfilRate();

    //... find underdrain flow rate
    StorageDrain = 0.0;
    head = storageDepth - theLidProc->drain.offset;
    if ( theLidProc->drain.coeff > 0.0 && head >= 0.0 )
    {
        if ( storageDepth >= theLidProc->storage.thickness )
        {
            head += (soilTheta - theLidProc->soil.fieldCap) /
                    (theLidProc->soil.porosity - theLidProc->soil.fieldCap) *
                    theLidProc->soil.thickness;
            if ( soilTheta >= theLidProc->soil.porosity ) head += surfaceDepth;
        }
        StorageDrain =  getStorageDrainRate(head);
    }

    //... special case of no storage layer present
    if ( theLidProc->storage.thickness == 0.0 )
    {
        StorageEvap = 0.0;
        maxRate = MIN(StorageInfil, SoilPerc);
        SoilPerc = maxRate;
        StorageInfil = maxRate;
    }

    //... both storage & soil layers are saturated
    else if ( storageDepth >= theLidProc->storage.thickness &&
        soilTheta >= theLidProc->soil.porosity )
    {
        //... soil perc can't exceed storage outflow
        maxRate = StorageDrain + StorageInfil;
        if ( SoilPerc > maxRate ) SoilPerc = maxRate;

        //... storage outflow can't exceed soil perc
        else
        {
            //... use up available drain capacity first
            StorageDrain = MIN(StorageDrain, SoilPerc);
            StorageInfil = SoilPerc - StorageDrain;
        }
    }

    //... layers not saturated
    else
    {
        //... limit underdrain flow by volume above drain offset
        if ( StorageDrain > 0.0 )
        {
            maxRate = (storageDepth - theLidProc->drain.offset) *
                      theLidProc->storage.voidFrac / Tstep;
            StorageDrain = MIN(StorageDrain, maxRate);
        }

        //... limit storage infil. by remaining volume
        maxRate = StorageVolume / Tstep - StorageDrain - StorageEvap;
        maxRate = MAX(0.0, maxRate);
        StorageInfil = MIN(StorageInfil, maxRate);

        //... limit soil perc by available storage volume
        availVolume = (theLidProc->storage.thickness - storageDepth) *
            theLidProc->storage.voidFrac;
        maxRate = availVolume/Tstep + StorageEvap + StorageDrain + StorageInfil;
        maxRate = MAX(maxRate, 0.0);
        SoilPerc = MIN(SoilPerc, maxRate);
    }

    //... limit surface infil. by available soil pore volume
    maxRate = (theLidProc->soil.porosity - soilTheta) * 
        theLidProc->soil.thickness / Tstep + SoilPerc;
    SurfaceInfil = MIN(SurfaceInfil, maxRate);

    //... find surface layer 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 - StorageInfil - StorageDrain) /
              theLidProc->storage.voidFrac;
}
Пример #7
0
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
//
{
    double surfaceDepth;
    double soilTheta;
    double storageDepth;
    double availVolume;
    double maxRate;

    //... retrieve state variables from work vector
    surfaceDepth = x[SURF];
    soilTheta = x[SOIL];
    storageDepth = x[STOR];

    //... convert state variables to volumes
    SurfaceVolume = surfaceDepth * theLidProc->surface.voidFrac;
    SoilVolume = soilTheta * theLidProc->soil.thickness;
    StorageVolume = storageDepth * theLidProc->storage.voidFrac;

    //... get ET rates
    availVolume = SoilVolume - theLidProc->soil.wiltPoint *
                   theLidProc->soil.thickness;
    getEvapRates(SurfaceVolume, availVolume, StorageVolume);

    //... no storage evap if soil layer saturated
    if ( soilTheta >= theLidProc->soil.porosity ) StorageEvap = 0.0;

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

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

    //... both storage & soil layers are saturated
    if ( storageDepth >= theLidProc->storage.thickness &&
        soilTheta >= theLidProc->soil.porosity )
    {
        //... soil perc can't exceed storage outflow
        if ( SoilPerc > StorageDrain ) SoilPerc = StorageDrain;

        //... storage outflow can't exceed soil perc
        else StorageDrain = MIN(StorageDrain, SoilPerc);
    }

    //... storage and/or soil layers not saturated
    else
    {
        //... limit underdrain flow by volume above drain offset
        if ( StorageDrain > 0.0 )
        {
            maxRate = (storageDepth - theLidProc->drain.offset) *
                      theLidProc->storage.voidFrac / Tstep;
            StorageDrain = MIN(StorageDrain, maxRate);
        }

        //... limit soil perc by available storage volume
        availVolume = (theLidProc->storage.thickness - storageDepth) *
            theLidProc->storage.voidFrac;
        maxRate = availVolume/Tstep + StorageEvap + StorageDrain;
        SoilPerc = MIN(SoilPerc, maxRate);
    }

    //... limit surface infil. by available soil pore volume
    maxRate = (theLidProc->soil.porosity - soilTheta) * 
        theLidProc->soil.thickness / Tstep + SoilPerc;
    SurfaceInfil = MIN(SurfaceInfil, maxRate);

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

    // ... find net fluxes for each layer
    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;
}