Friday, January 27, 2023

XPSWMM to ICM SWMM or ICM Process Pathways

 


#ProcessDescription
1Technical details about how XPSWMM models a featureThis process involves understanding the specific algorithms, equations, and data inputs used by XPSWMM to model different features of an urban drainage system, such as hydrology, hydraulics, and water quality. This includes understanding how XPSWMM calculates runoff, infiltration, evaporation, and other hydrologic processes, as well as how it models the flow and routing of water through the drainage system.
2The process of exporting a XPSWMM model to XPXThis process involves using the export functionality in XPSWMM to save the model in a format that can be used in the XPX software. This includes selecting the components of the model to export, specifying the export location, and ensuring that the exported file is in a format that can be read by XPX.
3The process of exporting a XPSWMM model to SWMM5This process involves using the export functionality in XPSWMM to save the model in a format that can be used in the SWMM5 software. This includes selecting the components of the model to export, specifying the export location, and ensuring that the exported file is in a format that can be read by SWMM5.
4The process of importing the SWMM5 model to ICM SWMMThis process involves using the import functionality in ICM SWMM to load the model exported from SWMM5. This includes specifying the location of the exported file, mapping the components of the model to the appropriate inputs in ICM SWMM, and checking for any errors or inconsistencies in the imported model.
5The process of importing the SWMM5 model to ICMThis process involves using the import functionality in ICM to load the model exported from SWMM5. This includes specifying the location of the exported file, mapping the components of the model to the appropriate inputs in ICM, and checking for any errors or inconsistencies in the imported model.
6Validating the ICM SWMM ImportThis process involves checking the imported model in ICM SWMM for errors or inconsistencies. This includes comparing the imported data to the original XPSWMM model, checking for missing or incorrect data, and making any necessary adjustments to the imported model before running the simulation.
7Converting the ICM SWMM network to ICMThis process involves converting the imported model in ICM SWMM to the format used by the ICM software. This includes mapping the components of the model to the appropriate inputs in ICM, and making any necessary adjustments to the imported model before running the simulation.
8Getting either ICM or ICM SWMM to runThis process involves configuring the software and the model, and then running the simulation. This includes setting the simulation parameters, specifying the time step and duration of the simulation, and specifying the output options.
9Compare answers to XPSWMMThis process involves comparing the results of the XPSWMM simulation to the results of the simulation run in ICM or ICM SWMM. This includes comparing the hydrographs, water surface elevations, and other output variables, and identifying any discrepancies or issues with the results.
10Technical details on how SWMM5 or ICM work compared to XPSWMMThis process involves identifying and implementing solutions to issues or problems that may arise during the use of the software or the simulation.

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;
}

GitHub code and Markdown (MD) files Leveraging

 To better achieve your goal of leveraging your GitHub code and Markdown (MD) files for your WordPress blog or LinkedIn articles, consider t...