Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add storage node get/set (Setting functional curve coefficient) #189

Open
bemcdonnell opened this issue Jul 24, 2018 · 13 comments · May be fixed by #192
Open

add storage node get/set (Setting functional curve coefficient) #189

bemcdonnell opened this issue Jul 24, 2018 · 13 comments · May be fixed by #192
Labels
Milestone

Comments

@bemcdonnell
Copy link
Member

bemcdonnell commented Jul 24, 2018

Issue Carried over from PySWMM: (pyswmm/pyswmm#167)

@joaolponciano, let's discuss the implementation over here. Once the API is opened, it is easy to interface pyswmm with it.

@joaolponciano
Copy link

Awesome. So I was think how to do it, and I thought to take the parser used for get/set nodes parameters and modify it to fit into the storage parameters. Do you think this could work?

@michaeltryby
Copy link

The EPANET API has curve editing capabilities. Then the curve gets associated with a model element. This way all the different curve types are editable through the API.

So I would like to see more general curve editing capabilities implemented rather then something specific just for storage nodes. Make sense?

@dickinsonre
Copy link

A storage node or junction in SWMM5 can be a function with three parameter, AREA - A + B^C or a Storage Curve. Don't you need two API's : one for the Function and one for the Storage Curve (general API for Curves)

@bemcdonnell
Copy link
Member Author

@joaolponciano, I guess that I'm envisioning a few get/set functions for storage nodes.

For starters, specific to storage nodes the parser collects and populates the following properties pertaining to Storage Nodes:

int storage_readParams(int j, int k, char* tok[], int ntoks)
//
//  Input:   j = node index
//           k = storage unit index
//           tok[] = array of string tokens
//           ntoks = number of tokens
//  Output:  returns an error message
//  Purpose: reads a storage unit's properties from a tokenized line of input.
//
//  Format of input line is:
//     nodeID  elev  maxDepth  initDepth  FUNCTIONAL a1 a2 a0 aPond fEvap (infil)
//     nodeID  elev  maxDepth  initDepth  TABULAR    curveID  aPond fEvap (infil)
//

I envision the following functions available for a Node-Storage Object. The other properties such as elev, maxDepth, and initDepth shoudl already be available through swmm_[get/set]NodeParam()

swmm_getStorageCurve(int index, int *curve_index)
{
//output index of curve
}

swmm_setStorageCurve(int index, int curve_index)
{
//sets curve to TABULAR (if not already) and pushes index
// need validation
}

swmm_getStorageFunc(int index, double *a1, double *a2, double *a3)
{
//get function params
}

swmm_setStorageFunc(int index, double a1, double a2, double a3)
{
 //sets curve to FUNCTIONAL (if not already) and pushes parameters
// need validation
}

swmm_getStorageExfil(int index, int *rate)
{
//get constant exfiltration rate (not the same as current exfil rate)
}

swmm_setStorageExfil(int index, int rate)
{
//set Storage Exfil
// may need validation
}

swmm_getStorageEvap(int index, int *rate)
{
//get constant evap rate (not the same as current evap rate)
}

swmm_setStorageEvap(int index, int rate)
{
//set evap rate
// may need validation
}

Why don't you study swmm_[get/set]NodeParams() in toolkitAPI.c and see if you can come up with some strategies to extract these data through the functions described above.

@michaeltryby
Copy link

We could make the api more compact and functional by handling multiple properties with a single api call.

@joaolponciano
Copy link

@bemcdonnell, I've tried doing something similar to what is done for the nodes, but I'm not so sure if I have to implement the function curve equations again (and how to implement something about the tabular curve) and I have some doubts about the evaporation and exfil units. I thought something like that:

int DLLEXPORT swmm_getStorageParam(int index, int Param, double *value)
//
// Input: index = Index of desired ID
// param = Parameter desired (Based on enum SM_StorageProperty)
// Output: value = value to be output
// Return: API Error
// Purpose: Gets Storage Parameter
{
int errcode = 0;
*value = 0;
// Check if Open
if(swmm_IsOpenFlag() == FALSE)
{
errcode = ERR_API_INPUTNOTOPEN;
}
// Check if object index is within bounds
else if (index < 0 || index >= Nobjects[Storage])
{
errcode = ERR_API_OBJECT_INDEX;
}
else
{
switch(Param)
{
case SM_STORAGECURVE:
*value = Storage[index].aCurve * UCF(VOLUME); break;
case SM_STORAGEFUNC:
*value = Storage[index].functional * UCF(VOLUME); break;
case SM_STORAGECOEFFICIENT:
*value = Storage[index].aCoeff * UCF(LENGTH) * UCF(LENGTH); break;
case SM_STORAGEEXFIL:
*value = Storage[index].exfil * UCF(FLOW); break;
case SM_STORAGEEVAP:
*value = Storage[index].fEvap * UCF(EVAPRATE); break;
default: errcode = ERR_API_OUTBOUNDS; break;
}
}
return(errcode);
}

// Set Storage Parameters

int DLLEXPORT swmm_setStorage Param(int index, int Param, double value)
//
// Input: index = Index of desired ID
// param = Parameter desired (Based on enum SM_StorageProperty)
// value = value to be input
// Return: API Error
// Purpose: Sets Storage Parameter
{
int errcode = 0;
// Check if Open
if(swmm_IsOpenFlag() == FALSE)
{
errcode = ERR_API_INPUTNOTOPEN;
}
// Check if Simulation is Running
else if(swmm_IsStartedFlag() == TRUE)
{
errcode = ERR_API_SIM_NRUNNING;
}
// Check if object index is within bounds
else if (index < 0 || index >= Nobjects[STORAGE])
{
errcode = ERR_API_OBJECT_INDEX;
}
else
{
switch(Param)
{
case SM_STORAGECURVE:
*value = Storage[index].aCurve * UCF(VOLUME); break;
case SM_STORAGEFUNC:
*value = Storage[index].functional * UCF(VOLUME); break;
case SM_STORAGECOEFFICIENT:
*value = Storage[index].aCoeff * UCF(LENGTH) * UCF(LENGTH); break;
case SM_STORAGEEXFIL:
*value = Storage[index].exfil * UCF(FLOW); break;
case SM_STORAGEEVAP:
*value = Storage[index].fEvap * UCF(EVAPRATE); break;
default: errcode = ERR_API_OUTBOUNDS; break;
}
}
// Need to re-validate
//storage_validate(index)
return(errcode);
}

Thanks for your help and attention.

@bemcdonnell
Copy link
Member Author

@joaolponciano, go ahead and issue a pull request and we can discuss the implementation there. "Issues" are normally to discuss concepts.

@dickinsonre
Copy link

I have a question, is this all to model changing areas in a storage node over a period of years? I like the idea but if we had time series tied to all SWMM5 parameters then it might be easier to do this.

@bemcdonnell
Copy link
Member Author

@dickinsonre, it appears in the code block that this API function will be shut off during simulation time. Which I think is good. I would worry about creating or destroying mass if the node area were to change over time.

@dickinsonre
Copy link

1, A workaround would be to test for th node depth, if the storage node was dry and the pond increased in area there would not be any mass balance issues in a continuous simulation.

  1. Mass balance happens already in a ponded node, the volume and depth change all of the time but no worries as the volume is conserved for the next time.

@joaolponciano
Copy link

@bemcdonnell, I created a pull and insert that parser there.

@bemcdonnell
Copy link
Member Author

@joaolponciano, it looks like your pointed your PR to USEPA. Please point it to OpenWaterAnalytics/Stormwater-Management-Model ‘dev’ branch

@joaolponciano
Copy link

Sorry, I did not pay attention to this when I submitted the pull, I think it's now in the right place.

@joaolponciano joaolponciano linked a pull request Aug 15, 2018 that will close this issue
@bemcdonnell bemcdonnell added Easy Easy Issue and removed Moderate Moderately Challenging Task labels Aug 15, 2018
@bemcdonnell bemcdonnell modified the milestones: v5.2.0.dev5, v5.3.0.dev0 Jul 30, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants