@@ -10,6 +10,7 @@ from warnings import warn
10
10
from typing import List, Tuple, Union, Optional, Dict, Set, Callable
11
11
from cpython.datetime cimport datetime, timedelta
12
12
from libc.stdlib cimport free, malloc
13
+ from functools import partialmethod
13
14
14
15
# external imports
15
16
@@ -105,7 +106,7 @@ class SWMMObjects(Enum):
105
106
:type SYSTEM: int
106
107
"""
107
108
RAIN_GAGE = swmm_Object.swmm_GAGE
108
- SUBCATCH = swmm_Object.swmm_SUBCATCH
109
+ SUBCATCHMENT = swmm_Object.swmm_SUBCATCH
109
110
NODE = swmm_Object.swmm_NODE
110
111
LINK = swmm_Object.swmm_LINK
111
112
AQUIFER = swmm_Object.swmm_AQUIFER
@@ -450,6 +451,7 @@ class SWMMSystemProperties(Enum):
450
451
IGNORE_GROUNDWATER = swmm_SystemProperty.swmm_IGNOREGROUNDWATER
451
452
IGNORE_ROUTING = swmm_SystemProperty.swmm_IGNOREROUTING
452
453
IGNORE_QUALITY = swmm_SystemProperty.swmm_IGNOREQUALITY
454
+ ERROR_CODE = swmm_SystemProperty.swmm_ERROR_CODE
453
455
RULE_STEP = swmm_SystemProperty.swmm_RULESTEP
454
456
SWEEP_START = swmm_SystemProperty.swmm_SWEEPSTART
455
457
SWEEP_END = swmm_SystemProperty.swmm_SWEEPEND
@@ -712,8 +714,9 @@ cdef class Solver:
712
714
cdef clock_t _clock
713
715
cdef double _total_duration
714
716
cdef object _solver_state
717
+ cdef object _partial_step_function
715
718
716
- def __cinit__(self , str inp_file , str rpt_file , str out_file , bint save_results = True ):
719
+ def __cinit__(self , str inp_file , str rpt_file , str out_file , int stride_step = 300 , bint save_results = True ):
717
720
"""
718
721
Constructor to create a new SWMM solver.
719
722
@@ -725,6 +728,7 @@ cdef class Solver:
725
728
self ._save_results = save_results
726
729
self ._inp_file = inp_file
727
730
self ._progress_callbacks_per_second = 2
731
+ self ._stride_step = stride_step
728
732
self ._clock = clock()
729
733
global_solver = self
730
734
@@ -738,8 +742,6 @@ cdef class Solver:
738
742
else :
739
743
self ._out_file = inp_file.replace(' .inp' , ' .out' )
740
744
741
- self ._stride_step = 0
742
-
743
745
self ._callbacks = {
744
746
CallbackType.BEFORE_INITIALIZE: [],
745
747
CallbackType.BEFORE_OPEN: [],
@@ -932,6 +934,8 @@ cdef class Solver:
932
934
"""
933
935
cdef int count = swmm_getCount(object_type.value)
934
936
937
+ self.__validate_error(count )
938
+
935
939
return count
936
940
937
941
def get_object_name(self , object_type: SWMMObjects , index: int ) -> str:
@@ -946,8 +950,8 @@ cdef class Solver:
946
950
:rtype: str
947
951
"""
948
952
cdef char* c_object_name = < char * > malloc(1024 * sizeof(char ))
949
- cdef int error_code = swmm_getName(object_type.value, index, c_object_name, 1024 )
950
953
954
+ cdef int error_code = swmm_getName(object_type.value, index, c_object_name, 1024 )
951
955
self.__validate_error(error_code )
952
956
953
957
object_name = c_object_name.decode(' utf-8' )
@@ -956,6 +960,32 @@ cdef class Solver:
956
960
957
961
return object_name
958
962
963
+ def get_object_names(self , object_type: SWMMObjects ) -> List[str]:
964
+ """
965
+ Get the names of all SWMM objects of a given type.
966
+
967
+ :param object_type: SWMM object type
968
+ :type object_type: SWMMObjects
969
+ :return: Object names
970
+ :rtype: List[str]
971
+ """
972
+ cdef char* c_object_name = < char * > malloc(1024 * sizeof(char ))
973
+ cdef list object_names = []
974
+ cdef int count = self .get_object_count(object_type)
975
+
976
+ for i in range(count ):
977
+
978
+ error_code = swmm_getName(object_type.value, i, c_object_name, 1024 )
979
+ self .__validate_error(error_code)
980
+
981
+ object_name = c_object_name.decode(' utf-8' )
982
+ object_names.append(object_name)
983
+
984
+
985
+ free(c_object_name)
986
+
987
+ return object_names
988
+
959
989
def get_object_index (self , object_type: SWMMObjects , object_name: str ) -> int:
960
990
"""
961
991
Get the index of a SWMM object.
@@ -971,7 +1001,7 @@ cdef class Solver:
971
1001
972
1002
return index
973
1003
974
- cpdef void set_value(self , int object_type , int property_type , int index , int sub_index , double value ):
1004
+ cpdef void set_value(self , int object_type , int property_type , int index , double value , int sub_index = - 1 ):
975
1005
"""
976
1006
Set a SWMM system property value.
977
1007
@@ -989,7 +1019,7 @@ cdef class Solver:
989
1019
cdef int error_code = swmm_setValueExpanded(object_type, property_type, index, sub_index, value)
990
1020
self .__validate_error(error_code)
991
1021
992
- cpdef double get_value(self , int object_type, int property_type, int index, int sub_index):
1022
+ cpdef double get_value(self , int object_type, int property_type, int index, int sub_index = - 1 ):
993
1023
"""
994
1024
Get a SWMM system property value.
995
1025
@@ -999,6 +1029,8 @@ cdef class Solver:
999
1029
:rtype: double
1000
1030
"""
1001
1031
cdef double value = swmm_getValueExpanded(object_type, property_type, index, sub_index)
1032
+ self .__validate_error(< int > value)
1033
+
1002
1034
return value
1003
1035
1004
1036
@property
@@ -1009,7 +1041,7 @@ cdef class Solver:
1009
1041
:return: Stride step
1010
1042
:rtype: int
1011
1043
"""
1012
- pass
1044
+ return self. _stride_step
1013
1045
1014
1046
@stride_step.setter
1015
1047
def stride_step(self , value: int ):
@@ -1019,7 +1051,7 @@ cdef class Solver:
1019
1051
:param value: Stride step in seconds
1020
1052
:type value: int
1021
1053
"""
1022
- pass
1054
+ self ._stride_step = value
1023
1055
1024
1056
@property
1025
1057
def solver_state (self ) -> SolverState:
@@ -1078,18 +1110,11 @@ cdef class Solver:
1078
1110
self .__validate_error(error_code)
1079
1111
self ._solver_state = SolverState.OPEN
1080
1112
self .__execute_callbacks(CallbackType.AFTER_OPEN)
1081
-
1082
- self .__execute_callbacks(CallbackType.BEFORE_START)
1083
- error_code = swmm_start(self ._save_results)
1084
- self .__validate_error(error_code)
1085
- self ._solver_state = SolverState.STARTED
1086
- self .__execute_callbacks(CallbackType.AFTER_START)
1087
1113
else :
1088
1114
raise SWMMSolverException(f' Initialize failed: Solver is not in a valid state: {self._solver_state}' )
1089
1115
1090
-
1091
1116
self ._total_duration = swmm_getValue(SWMMSystemProperties.END_DATE.value, 0 ) - swmm_getValue(SWMMSystemProperties.START_DATE.value, 0 )
1092
-
1117
+
1093
1118
cpdef double step(self ):
1094
1119
"""
1095
1120
Step a SWMM simulation.
@@ -1100,6 +1125,13 @@ cdef class Solver:
1100
1125
cdef double elapsed_time = 0.0
1101
1126
cdef double progress = 0.0
1102
1127
1128
+ if self ._solver_state == SolverState.OPEN:
1129
+ self .__execute_callbacks(CallbackType.BEFORE_START)
1130
+ error_code = swmm_start(self ._save_results)
1131
+ self .__validate_error(error_code)
1132
+ self ._solver_state = SolverState.STARTED
1133
+ self .__execute_callbacks(CallbackType.AFTER_START)
1134
+
1103
1135
if self ._stride_step > 0 :
1104
1136
error_code = swmm_stride(self ._stride_step, & elapsed_time)
1105
1137
else :
@@ -1241,8 +1273,13 @@ cdef class Solver:
1241
1273
:param error_code: Error code to validate
1242
1274
:type error_code: int
1243
1275
"""
1244
- if error_code != 0 :
1245
- raise SWMMSolverException(f' SWMM failed with message: {self.__get_error()}' )
1276
+ cdef int internal_error_code = < int > swmm_getValue(SWMMObjects.SYSTEM.value, SWMMSystemProperties.ERROR_CODE.value)
1277
+
1278
+ if error_code < 0 :
1279
+ if internal_error_code > 0 :
1280
+ raise SWMMSolverException(f' SWMM failed with message: {internal_error_code}, {self.__get_error()}' )
1281
+ else :
1282
+ raise SWMMSolverException(f' SWMM failed with message: {error_code}, {get_error_message(error_code)}' )
1246
1283
1247
1284
cdef str __get_error(self ):
1248
1285
"""
0 commit comments