pyswmm / Stormwater-Management-Model

PySWMM Stormwater Management Model repository
Other
99 stars 77 forks source link

solver/lid: Check if suction head is negative in validateLidProc #359

Closed easyteacher closed 1 year ago

easyteacher commented 2 years ago

When validating LID process parameters, the suction head should be also validated. According to "Storm Water Management Model User's Manual Version 5.1", "suction head" should be >=0, so add a check in validateLidProc to make sure "suction" is also valid.

bemcdonnell commented 2 years ago

@dickinsonre, do you agree?

dickinsonre commented 2 years ago

I almost agree - it does seem both the SWMM5 GUI and the SWMM5 engine allow a value of zero for the suction head - see readSoilData in LID.C You can also have a zero value of suction head for a subcatchment as well. Not sure that makes sense but you can set the head to zero, validate the model and the model runs for both LID and Subcatchments. Suction head cannot be less than zero.

easyteacher commented 2 years ago

I found that not all parameters were checked in validateLidProc. Is that an intended behavior or just something that needs to be fixed? For example: surface.voidFrac and surface.sideSlope

dickinsonre commented 2 years ago

Going by what the SWMM5 C code does - voidFrac is checked but a zero value for sideSlope is okay

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];
dickinsonre commented 2 years ago

Checking to see if that makes sense - if you have a side slope of 0 the engine will correct that and use a width of 0.5 feet (internal SWMM5 units) - this applies to both bottom and top width - Maybe PySWMM should be stricter in its checking?

//... get swale's bottom width
//    (0.5 ft minimum to avoid numerical problems)
slope = theLidProc->surface.sideSlope;
topWidth = theLidUnit->fullWidth;
topWidth = MAX(topWidth, 0.5);
botWidth = topWidth - 2.0 * slope * theLidProc->surface.thickness;
if ( botWidth < 0.5 )
{
    botWidth = 0.5;
    slope = 0.5 * (topWidth - 0.5) / theLidProc->surface.thickness;
}
easyteacher commented 2 years ago

Going by what the SWMM5 C code does - voidFrac is checked but a zero value for sideSlope is okay

Should validateLidProc also check the validity of all parameters?

  1. swmm_setLidCParam sets lidProc->surface.voidFrac = 1 - value; and calls lid_validateLidProc
  2. lid_validateLidProc calls validateLidProc (No check here!)

But reading from input is safe, because project_readInput also checks the validity.

  1. swmm_open calls project_readInput and project_validate
  2. project_validate calls lid_validate
  3. lid_validate calls validateLidProc