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

API for getting/setting RDII parameters #266

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from
39 changes: 39 additions & 0 deletions include/toolkitAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,28 @@ typedef enum {
SM_SURCHDEPTH = 2, /**< Surcharge Depth */
SM_PONDAREA = 3, /**< Ponding Area */
SM_INITDEPTH = 4, /**< Initial Depth */
SM_RDIIIND = 5, /**< Unit hydrograph index */
SM_RDIIAREA = 6, /**< Contributing area for the node */
} SM_NodeProperty;

/// Unit hydrograph property codes
typedef enum {
SM_RTK_ALL = 0, /**< RTK for ALL */
SM_RTK_JAN = 1, /**< RTK for JAN */
SM_RTK_FEB = 2, /**< RTK for FEB */
SM_RTK_MAR = 3, /**< RTK for MAR */
SM_RTK_APR = 4, /**< RTK for APR */
SM_RTK_MAY = 5, /**< RTK for MAY */
SM_RTK_JUN = 6, /**< RTK for JUN */
SM_RTK_JUL = 7, /**< RTK for JUL */
SM_RTK_AUG = 8, /**< RTK for AUG */
SM_RTK_SEP = 9, /**< RTK for SEP */
SM_RTK_OCT = 10, /**< RTK for OCT */
SM_RTK_NOV = 11, /**< RTK for NOV */
SM_RTK_DEC = 12, /**< RTK for DEC */
SM_RAINGAGE = 13, /**< Rain gage for the hydrograph */
} SM_HydrographProp;

/// Link property codes
typedef enum {
SM_OFFSET1 = 0, /**< Inlet Offset */
Expand Down Expand Up @@ -1116,6 +1136,25 @@ int DLLEXPORT swmm_setOutfallStage(int index, double stage);
*/
int DLLEXPORT swmm_setGagePrecip(int index, double total_precip);

/**
@brief Get rtk values for a specified hydrograph.
@param index The index of a hydrograph
@param Param The property type code(See @ref SM_HydrographProp)
@param[out] rdii_array The rtk values of the hydrograph.
@return Error code
*/
int DLLEXPORT swmm_getRDIIParams(int index, int Param, double *rdii_array);

/**
@brief Set rtk values for a specified hydrograph.
@param index The index of a hydrograph
@param Param The property type code(See @ref SM_HydrographProp)
@param[out] value The rtk values of the hydrograph to be set.
@return Error code
*/
int DLLEXPORT swmm_setRDIIParams(int index, int Param, double *value);


/**
@brief Helper function to free memory array allocated in SWMM.
@param array The pointer to the array
Expand Down
138 changes: 138 additions & 0 deletions src/toolkitAPI.c
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,10 @@ int DLLEXPORT swmm_getNodeParam(int index, int Param, double *value)
*value = Node[index].pondedArea * UCF(LENGTH) * UCF(LENGTH); break;
case SM_INITDEPTH:
*value = Node[index].initDepth * UCF(LENGTH); break;
case SM_RDIIIND:
*value = (double)Node[index].rdiiInflow->unitHyd; break;
case SM_RDIIAREA:
*value = Node[index].rdiiInflow->area * UCF(LANDAREA); break;
default: error_code_index = ERR_API_OUTBOUNDS; break;
}
}
Expand All @@ -557,6 +561,7 @@ int DLLEXPORT swmm_setNodeParam(int index, int Param, double value)
/// Purpose: Sets Node Parameter
{
int error_code_index = 0;
int unit_hyd_index = -1;
// Check if Open
if(swmm_IsOpenFlag() == FALSE)
{
Expand Down Expand Up @@ -586,6 +591,25 @@ int DLLEXPORT swmm_setNodeParam(int index, int Param, double value)
Node[index].pondedArea = value / ( UCF(LENGTH) * UCF(LENGTH) ); break;
case SM_INITDEPTH:
Node[index].initDepth = value / UCF(LENGTH); break;
case SM_RDIIIND:
unit_hyd_index = (int)round(value);
if (unit_hyd_index < 0 || unit_hyd_index >= Nobjects[SM_UNITHYD])
{
error_code_index = ERR_API_OBJECT_INDEX; break;
}
else
{
Node[index].rdiiInflow->unitHyd = unit_hyd_index; break;
}
case SM_RDIIAREA:
if (value < 0.0)
{
error_code_index = ERR_RDII_AREA; break;
}
else
{
Node[index].rdiiInflow->area = value / UCF(LANDAREA); break;
}
default: error_code_index = ERR_API_OUTBOUNDS; break;
}
}
Expand Down Expand Up @@ -2600,6 +2624,120 @@ int DLLEXPORT swmm_getLidUResult(int index, int lidIndex, int type, double *resu
return error_getCode(error_code_index);
}

int DLLEXPORT swmm_getRDIIParams(int index, int Param, double *rdii_array)
///
/// Input: index = Index of the desired hydrograph
/// Param = number from (0 through 12) to indicate month index (0 = ALL)
/// Output: an 1d-array of size 18 containing the rtk and ia values of the hydrograph
/// in a columnwise fashion (as they are structured in the INP file).
/// Return: API Error
/// Purpose: get all information about a particular hydrograph
{
int errcode = 0;
int m = Param; // month index
int i;
double t, k;

// Check if Open
if (swmm_IsOpenFlag() == FALSE) {
errcode = ERR_API_INPUTNOTOPEN;
}
// Check if object index is within bounds
else if (index < 0 || index >= Nobjects[UNITHYD]) {
errcode = ERR_API_OBJECT_INDEX;
}
else if (m < 0 || m > 12) {
errcode = ERR_API_OUTBOUNDS;
}
else {
if (m > 0) m--;
for (i = 0; i < 3; i++) {
rdii_array[i] = UnitHyd[index].r[m][i];
t = (double)UnitHyd[index].tPeak[m][i];
k = (double)UnitHyd[index].tBase[m][i];
k = k / t - 1;
t /= 3600.0; // seconds to hour
rdii_array[i + 3] = t;
rdii_array[i + 6] = k;
rdii_array[i + 9] = UnitHyd[index].iaMax[m][i];
rdii_array[i + 12] = UnitHyd[index].iaRecov[m][i];
rdii_array[i + 15] = UnitHyd[index].iaInit[m][i];
}
}
return (errcode);
}

int DLLEXPORT swmm_setRDIIParams(int index, int Param, double *value)
///
/// Input: index = Index of desired unit hydrograph
/// value = a 1-d array of 18 doubles containing rtk values to be set.
/// The array should be ordered in columnwise fashion
/// as entered in the INP file with the same units, e.g.,
/// value[0] = r1, value[1] = r2, value[2] = r3,
/// value[4] = t1, value[5] = t2, ...
/// Output: returns API Error
/// Purpose: Sets RTK and IA values for a unit hydrograph
{
int errcode = 0;
int m = Param; // month index
int i, im, m1, m2;
double t, k;
long seconds;

// Check if values passed are all positive
for (i = 0; i < 18; i++) {
if (value[i] < 0) {
errcode = ERR_UNITHYD_RATIOS;
break;
}
}
// Check if sum of R values are <= 1
if ((value[0] + value[1] + value[2]) > 1.01) {
errcode = ERR_UNITHYD_RATIOS;
}
// Check if Open
if (!errcode && (swmm_IsOpenFlag() == FALSE)) {
errcode = ERR_API_INPUTNOTOPEN;
}
else if (swmm_IsStartedFlag() == TRUE) {
errcode = ERR_API_SIM_NRUNNING;
}
// Check if object index is within bounds
else if (index < 0 || index >= Nobjects[UNITHYD]) {
errcode = ERR_API_OBJECT_INDEX;
}
else if (m < 0 || m > 12) {
errcode = ERR_API_OUTBOUNDS;
}
else {
if (m > 0) {
m1 = m - 1;
m2 = m1 + 1;
}
else {
m1 = 0;
m2 = m1 + 12;
}

for (im = m1; im < m2; im++) {
for (i = 0; i < 3; i++) {
UnitHyd[index].r[im][i] = value[i];
t = value[i + 3] * 3600;
seconds = (long)t;
UnitHyd[index].tPeak[im][i] = seconds;
k = value[i + 6];
k = (1 + k) * t; // tbase
seconds = (long)k;
UnitHyd[index].tBase[im][i] = seconds;
UnitHyd[index].iaMax[im][i] = value[i + 9];
UnitHyd[index].iaRecov[im][i] = value[i + 12];
UnitHyd[index].iaInit[im][i] = value[i + 15];
}
}
}
return error_getCode(errcode);
}

//-------------------------------
// Setters API
//-------------------------------
Expand Down
Loading