HydPy 6.2.dev1__cp313-cp313-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (890) hide show
  1. hydpy/__init__.py +275 -0
  2. hydpy/aliases.py +2554 -0
  3. hydpy/auxs/__init__.py +0 -0
  4. hydpy/auxs/anntools.py +1305 -0
  5. hydpy/auxs/armatools.py +883 -0
  6. hydpy/auxs/calibtools.py +3337 -0
  7. hydpy/auxs/interptools.py +1094 -0
  8. hydpy/auxs/iuhtools.py +543 -0
  9. hydpy/auxs/networktools.py +597 -0
  10. hydpy/auxs/ppolytools.py +809 -0
  11. hydpy/auxs/quadtools.py +61 -0
  12. hydpy/auxs/roottools.py +228 -0
  13. hydpy/auxs/smoothtools.py +273 -0
  14. hydpy/auxs/statstools.py +2125 -0
  15. hydpy/auxs/validtools.py +81 -0
  16. hydpy/conf/HydPyConfigBase.xsd +68637 -0
  17. hydpy/conf/HydPyConfigBase.xsdt +358 -0
  18. hydpy/conf/HydPyConfigMultipleRuns.xsd +25 -0
  19. hydpy/conf/HydPyConfigSingleRun.xsd +24 -0
  20. hydpy/conf/__init__.py +0 -0
  21. hydpy/conf/a_coefficients_explicit_lobatto_sequence.npy +0 -0
  22. hydpy/conf/support_points_for_smoothpar_logistic2.npy +0 -0
  23. hydpy/config.py +42 -0
  24. hydpy/core/__init__.py +0 -0
  25. hydpy/core/aliastools.py +214 -0
  26. hydpy/core/autodoctools.py +1947 -0
  27. hydpy/core/auxfiletools.py +1169 -0
  28. hydpy/core/devicetools.py +3810 -0
  29. hydpy/core/exceptiontools.py +269 -0
  30. hydpy/core/filetools.py +1985 -0
  31. hydpy/core/hydpytools.py +3089 -0
  32. hydpy/core/importtools.py +1398 -0
  33. hydpy/core/indextools.py +345 -0
  34. hydpy/core/itemtools.py +1849 -0
  35. hydpy/core/masktools.py +460 -0
  36. hydpy/core/modeltools.py +4868 -0
  37. hydpy/core/netcdftools.py +2683 -0
  38. hydpy/core/objecttools.py +2023 -0
  39. hydpy/core/optiontools.py +1045 -0
  40. hydpy/core/parametertools.py +4674 -0
  41. hydpy/core/printtools.py +222 -0
  42. hydpy/core/propertytools.py +643 -0
  43. hydpy/core/pubtools.py +254 -0
  44. hydpy/core/selectiontools.py +1571 -0
  45. hydpy/core/sequencetools.py +4476 -0
  46. hydpy/core/seriestools.py +339 -0
  47. hydpy/core/testtools.py +2483 -0
  48. hydpy/core/timetools.py +3567 -0
  49. hydpy/core/typingtools.py +333 -0
  50. hydpy/core/variabletools.py +2615 -0
  51. hydpy/cythons/__init__.py +24 -0
  52. hydpy/cythons/annutils.pxd +33 -0
  53. hydpy/cythons/annutils.pyi +25 -0
  54. hydpy/cythons/annutils.pyx +120 -0
  55. hydpy/cythons/autogen/__init__.py +0 -0
  56. hydpy/cythons/autogen/annutils.cp313-win_amd64.pyd +0 -0
  57. hydpy/cythons/autogen/annutils.pxd +42 -0
  58. hydpy/cythons/autogen/annutils.pyx +129 -0
  59. hydpy/cythons/autogen/c_arma.cp313-win_amd64.pyd +0 -0
  60. hydpy/cythons/autogen/c_arma.pxd +179 -0
  61. hydpy/cythons/autogen/c_arma.pyx +356 -0
  62. hydpy/cythons/autogen/c_arma_rimorido.cp313-win_amd64.pyd +0 -0
  63. hydpy/cythons/autogen/c_arma_rimorido.pxd +179 -0
  64. hydpy/cythons/autogen/c_arma_rimorido.pyx +356 -0
  65. hydpy/cythons/autogen/c_conv.cp313-win_amd64.pyd +0 -0
  66. hydpy/cythons/autogen/c_conv.pxd +198 -0
  67. hydpy/cythons/autogen/c_conv.pyx +491 -0
  68. hydpy/cythons/autogen/c_conv_idw.cp313-win_amd64.pyd +0 -0
  69. hydpy/cythons/autogen/c_conv_idw.pxd +124 -0
  70. hydpy/cythons/autogen/c_conv_idw.pyx +264 -0
  71. hydpy/cythons/autogen/c_conv_idw_ed.cp313-win_amd64.pyd +0 -0
  72. hydpy/cythons/autogen/c_conv_idw_ed.pxd +197 -0
  73. hydpy/cythons/autogen/c_conv_idw_ed.pyx +481 -0
  74. hydpy/cythons/autogen/c_conv_nn.cp313-win_amd64.pyd +0 -0
  75. hydpy/cythons/autogen/c_conv_nn.pxd +120 -0
  76. hydpy/cythons/autogen/c_conv_nn.pyx +224 -0
  77. hydpy/cythons/autogen/c_dam.cp313-win_amd64.pyd +0 -0
  78. hydpy/cythons/autogen/c_dam.pxd +805 -0
  79. hydpy/cythons/autogen/c_dam.pyx +1477 -0
  80. hydpy/cythons/autogen/c_dam_llake.cp313-win_amd64.pyd +0 -0
  81. hydpy/cythons/autogen/c_dam_llake.pxd +364 -0
  82. hydpy/cythons/autogen/c_dam_llake.pyx +705 -0
  83. hydpy/cythons/autogen/c_dam_lreservoir.cp313-win_amd64.pyd +0 -0
  84. hydpy/cythons/autogen/c_dam_lreservoir.pxd +365 -0
  85. hydpy/cythons/autogen/c_dam_lreservoir.pyx +708 -0
  86. hydpy/cythons/autogen/c_dam_lretention.cp313-win_amd64.pyd +0 -0
  87. hydpy/cythons/autogen/c_dam_lretention.pxd +340 -0
  88. hydpy/cythons/autogen/c_dam_lretention.pyx +625 -0
  89. hydpy/cythons/autogen/c_dam_pump.cp313-win_amd64.pyd +0 -0
  90. hydpy/cythons/autogen/c_dam_pump.pxd +402 -0
  91. hydpy/cythons/autogen/c_dam_pump.pyx +724 -0
  92. hydpy/cythons/autogen/c_dam_pump_sluice.cp313-win_amd64.pyd +0 -0
  93. hydpy/cythons/autogen/c_dam_pump_sluice.pxd +452 -0
  94. hydpy/cythons/autogen/c_dam_pump_sluice.pyx +829 -0
  95. hydpy/cythons/autogen/c_dam_sluice.cp313-win_amd64.pyd +0 -0
  96. hydpy/cythons/autogen/c_dam_sluice.pxd +404 -0
  97. hydpy/cythons/autogen/c_dam_sluice.pyx +726 -0
  98. hydpy/cythons/autogen/c_dam_v001.cp313-win_amd64.pyd +0 -0
  99. hydpy/cythons/autogen/c_dam_v001.pxd +452 -0
  100. hydpy/cythons/autogen/c_dam_v001.pyx +816 -0
  101. hydpy/cythons/autogen/c_dam_v002.cp313-win_amd64.pyd +0 -0
  102. hydpy/cythons/autogen/c_dam_v002.pxd +394 -0
  103. hydpy/cythons/autogen/c_dam_v002.pyx +703 -0
  104. hydpy/cythons/autogen/c_dam_v003.cp313-win_amd64.pyd +0 -0
  105. hydpy/cythons/autogen/c_dam_v003.pxd +417 -0
  106. hydpy/cythons/autogen/c_dam_v003.pyx +744 -0
  107. hydpy/cythons/autogen/c_dam_v004.cp313-win_amd64.pyd +0 -0
  108. hydpy/cythons/autogen/c_dam_v004.pxd +486 -0
  109. hydpy/cythons/autogen/c_dam_v004.pyx +891 -0
  110. hydpy/cythons/autogen/c_dam_v005.cp313-win_amd64.pyd +0 -0
  111. hydpy/cythons/autogen/c_dam_v005.pxd +524 -0
  112. hydpy/cythons/autogen/c_dam_v005.pyx +928 -0
  113. hydpy/cythons/autogen/c_dummy.cp313-win_amd64.pyd +0 -0
  114. hydpy/cythons/autogen/c_dummy.pxd +151 -0
  115. hydpy/cythons/autogen/c_dummy.pyx +263 -0
  116. hydpy/cythons/autogen/c_dummy_interceptedwater.cp313-win_amd64.pyd +0 -0
  117. hydpy/cythons/autogen/c_dummy_interceptedwater.pxd +69 -0
  118. hydpy/cythons/autogen/c_dummy_interceptedwater.pyx +104 -0
  119. hydpy/cythons/autogen/c_dummy_node2node.cp313-win_amd64.pyd +0 -0
  120. hydpy/cythons/autogen/c_dummy_node2node.pxd +89 -0
  121. hydpy/cythons/autogen/c_dummy_node2node.pyx +148 -0
  122. hydpy/cythons/autogen/c_dummy_snowalbedo.cp313-win_amd64.pyd +0 -0
  123. hydpy/cythons/autogen/c_dummy_snowalbedo.pxd +69 -0
  124. hydpy/cythons/autogen/c_dummy_snowalbedo.pyx +104 -0
  125. hydpy/cythons/autogen/c_dummy_snowcover.cp313-win_amd64.pyd +0 -0
  126. hydpy/cythons/autogen/c_dummy_snowcover.pxd +69 -0
  127. hydpy/cythons/autogen/c_dummy_snowcover.pyx +104 -0
  128. hydpy/cythons/autogen/c_dummy_snowycanopy.cp313-win_amd64.pyd +0 -0
  129. hydpy/cythons/autogen/c_dummy_snowycanopy.pxd +69 -0
  130. hydpy/cythons/autogen/c_dummy_snowycanopy.pyx +104 -0
  131. hydpy/cythons/autogen/c_dummy_soilwater.cp313-win_amd64.pyd +0 -0
  132. hydpy/cythons/autogen/c_dummy_soilwater.pxd +69 -0
  133. hydpy/cythons/autogen/c_dummy_soilwater.pyx +104 -0
  134. hydpy/cythons/autogen/c_evap.cp313-win_amd64.pyd +0 -0
  135. hydpy/cythons/autogen/c_evap.pxd +1029 -0
  136. hydpy/cythons/autogen/c_evap.pyx +2601 -0
  137. hydpy/cythons/autogen/c_evap_aet_hbv96.cp313-win_amd64.pyd +0 -0
  138. hydpy/cythons/autogen/c_evap_aet_hbv96.pxd +227 -0
  139. hydpy/cythons/autogen/c_evap_aet_hbv96.pyx +584 -0
  140. hydpy/cythons/autogen/c_evap_aet_minhas.cp313-win_amd64.pyd +0 -0
  141. hydpy/cythons/autogen/c_evap_aet_minhas.pxd +193 -0
  142. hydpy/cythons/autogen/c_evap_aet_minhas.pyx +478 -0
  143. hydpy/cythons/autogen/c_evap_aet_morsim.cp313-win_amd64.pyd +0 -0
  144. hydpy/cythons/autogen/c_evap_aet_morsim.pxd +681 -0
  145. hydpy/cythons/autogen/c_evap_aet_morsim.pyx +1642 -0
  146. hydpy/cythons/autogen/c_evap_pet_ambav1.cp313-win_amd64.pyd +0 -0
  147. hydpy/cythons/autogen/c_evap_pet_ambav1.pxd +532 -0
  148. hydpy/cythons/autogen/c_evap_pet_ambav1.pyx +1296 -0
  149. hydpy/cythons/autogen/c_evap_pet_hbv96.cp313-win_amd64.pyd +0 -0
  150. hydpy/cythons/autogen/c_evap_pet_hbv96.pxd +179 -0
  151. hydpy/cythons/autogen/c_evap_pet_hbv96.pyx +328 -0
  152. hydpy/cythons/autogen/c_evap_pet_m.cp313-win_amd64.pyd +0 -0
  153. hydpy/cythons/autogen/c_evap_pet_m.pxd +124 -0
  154. hydpy/cythons/autogen/c_evap_pet_m.pyx +214 -0
  155. hydpy/cythons/autogen/c_evap_pet_mlc.cp313-win_amd64.pyd +0 -0
  156. hydpy/cythons/autogen/c_evap_pet_mlc.pxd +126 -0
  157. hydpy/cythons/autogen/c_evap_pet_mlc.pyx +214 -0
  158. hydpy/cythons/autogen/c_evap_ret_fao56.cp313-win_amd64.pyd +0 -0
  159. hydpy/cythons/autogen/c_evap_ret_fao56.pxd +305 -0
  160. hydpy/cythons/autogen/c_evap_ret_fao56.pyx +624 -0
  161. hydpy/cythons/autogen/c_evap_ret_io.cp313-win_amd64.pyd +0 -0
  162. hydpy/cythons/autogen/c_evap_ret_io.pxd +112 -0
  163. hydpy/cythons/autogen/c_evap_ret_io.pyx +176 -0
  164. hydpy/cythons/autogen/c_evap_ret_tw2002.cp313-win_amd64.pyd +0 -0
  165. hydpy/cythons/autogen/c_evap_ret_tw2002.pxd +139 -0
  166. hydpy/cythons/autogen/c_evap_ret_tw2002.pyx +273 -0
  167. hydpy/cythons/autogen/c_exch.cp313-win_amd64.pyd +0 -0
  168. hydpy/cythons/autogen/c_exch.pxd +230 -0
  169. hydpy/cythons/autogen/c_exch.pyx +462 -0
  170. hydpy/cythons/autogen/c_exch_branch_hbv96.cp313-win_amd64.pyd +0 -0
  171. hydpy/cythons/autogen/c_exch_branch_hbv96.pxd +134 -0
  172. hydpy/cythons/autogen/c_exch_branch_hbv96.pyx +255 -0
  173. hydpy/cythons/autogen/c_exch_waterlevel.cp313-win_amd64.pyd +0 -0
  174. hydpy/cythons/autogen/c_exch_waterlevel.pxd +54 -0
  175. hydpy/cythons/autogen/c_exch_waterlevel.pyx +78 -0
  176. hydpy/cythons/autogen/c_exch_weir_hbv96.cp313-win_amd64.pyd +0 -0
  177. hydpy/cythons/autogen/c_exch_weir_hbv96.pxd +156 -0
  178. hydpy/cythons/autogen/c_exch_weir_hbv96.pyx +282 -0
  179. hydpy/cythons/autogen/c_ga.cp313-win_amd64.pyd +0 -0
  180. hydpy/cythons/autogen/c_ga.pxd +353 -0
  181. hydpy/cythons/autogen/c_ga.pyx +1204 -0
  182. hydpy/cythons/autogen/c_ga_garto.cp313-win_amd64.pyd +0 -0
  183. hydpy/cythons/autogen/c_ga_garto.pxd +330 -0
  184. hydpy/cythons/autogen/c_ga_garto.pyx +1105 -0
  185. hydpy/cythons/autogen/c_ga_garto_submodel1.cp313-win_amd64.pyd +0 -0
  186. hydpy/cythons/autogen/c_ga_garto_submodel1.pxd +236 -0
  187. hydpy/cythons/autogen/c_ga_garto_submodel1.pyx +944 -0
  188. hydpy/cythons/autogen/c_gland.cp313-win_amd64.pyd +0 -0
  189. hydpy/cythons/autogen/c_gland.pxd +437 -0
  190. hydpy/cythons/autogen/c_gland.pyx +726 -0
  191. hydpy/cythons/autogen/c_gland_gr4.cp313-win_amd64.pyd +0 -0
  192. hydpy/cythons/autogen/c_gland_gr4.pxd +382 -0
  193. hydpy/cythons/autogen/c_gland_gr4.pyx +605 -0
  194. hydpy/cythons/autogen/c_gland_gr5.cp313-win_amd64.pyd +0 -0
  195. hydpy/cythons/autogen/c_gland_gr5.pxd +368 -0
  196. hydpy/cythons/autogen/c_gland_gr5.pyx +568 -0
  197. hydpy/cythons/autogen/c_gland_gr6.cp313-win_amd64.pyd +0 -0
  198. hydpy/cythons/autogen/c_gland_gr6.pxd +420 -0
  199. hydpy/cythons/autogen/c_gland_gr6.pyx +673 -0
  200. hydpy/cythons/autogen/c_hland.cp313-win_amd64.pyd +0 -0
  201. hydpy/cythons/autogen/c_hland.pxd +855 -0
  202. hydpy/cythons/autogen/c_hland.pyx +2486 -0
  203. hydpy/cythons/autogen/c_hland_96.cp313-win_amd64.pyd +0 -0
  204. hydpy/cythons/autogen/c_hland_96.pxd +631 -0
  205. hydpy/cythons/autogen/c_hland_96.pyx +1724 -0
  206. hydpy/cythons/autogen/c_hland_96c.cp313-win_amd64.pyd +0 -0
  207. hydpy/cythons/autogen/c_hland_96c.pxd +621 -0
  208. hydpy/cythons/autogen/c_hland_96c.pyx +1822 -0
  209. hydpy/cythons/autogen/c_hland_96p.cp313-win_amd64.pyd +0 -0
  210. hydpy/cythons/autogen/c_hland_96p.pxd +683 -0
  211. hydpy/cythons/autogen/c_hland_96p.pyx +1911 -0
  212. hydpy/cythons/autogen/c_kinw.cp313-win_amd64.pyd +0 -0
  213. hydpy/cythons/autogen/c_kinw.pxd +509 -0
  214. hydpy/cythons/autogen/c_kinw.pyx +965 -0
  215. hydpy/cythons/autogen/c_kinw_williams.cp313-win_amd64.pyd +0 -0
  216. hydpy/cythons/autogen/c_kinw_williams.pxd +409 -0
  217. hydpy/cythons/autogen/c_kinw_williams.pyx +763 -0
  218. hydpy/cythons/autogen/c_kinw_williams_ext.cp313-win_amd64.pyd +0 -0
  219. hydpy/cythons/autogen/c_kinw_williams_ext.pxd +220 -0
  220. hydpy/cythons/autogen/c_kinw_williams_ext.pyx +440 -0
  221. hydpy/cythons/autogen/c_lland.cp313-win_amd64.pyd +0 -0
  222. hydpy/cythons/autogen/c_lland.pxd +1386 -0
  223. hydpy/cythons/autogen/c_lland.pyx +3679 -0
  224. hydpy/cythons/autogen/c_lland_dd.cp313-win_amd64.pyd +0 -0
  225. hydpy/cythons/autogen/c_lland_dd.pxd +679 -0
  226. hydpy/cythons/autogen/c_lland_dd.pyx +1719 -0
  227. hydpy/cythons/autogen/c_lland_knauf.cp313-win_amd64.pyd +0 -0
  228. hydpy/cythons/autogen/c_lland_knauf.pxd +1096 -0
  229. hydpy/cythons/autogen/c_lland_knauf.pyx +2784 -0
  230. hydpy/cythons/autogen/c_lland_knauf_ic.cp313-win_amd64.pyd +0 -0
  231. hydpy/cythons/autogen/c_lland_knauf_ic.pxd +1369 -0
  232. hydpy/cythons/autogen/c_lland_knauf_ic.pyx +3625 -0
  233. hydpy/cythons/autogen/c_meteo.cp313-win_amd64.pyd +0 -0
  234. hydpy/cythons/autogen/c_meteo.pxd +469 -0
  235. hydpy/cythons/autogen/c_meteo.pyx +879 -0
  236. hydpy/cythons/autogen/c_meteo_clear_glob_io.cp313-win_amd64.pyd +0 -0
  237. hydpy/cythons/autogen/c_meteo_clear_glob_io.pxd +75 -0
  238. hydpy/cythons/autogen/c_meteo_clear_glob_io.pyx +107 -0
  239. hydpy/cythons/autogen/c_meteo_glob_fao56.cp313-win_amd64.pyd +0 -0
  240. hydpy/cythons/autogen/c_meteo_glob_fao56.pxd +209 -0
  241. hydpy/cythons/autogen/c_meteo_glob_fao56.pyx +339 -0
  242. hydpy/cythons/autogen/c_meteo_glob_io.cp313-win_amd64.pyd +0 -0
  243. hydpy/cythons/autogen/c_meteo_glob_io.pxd +63 -0
  244. hydpy/cythons/autogen/c_meteo_glob_io.pyx +91 -0
  245. hydpy/cythons/autogen/c_meteo_glob_morsim.cp313-win_amd64.pyd +0 -0
  246. hydpy/cythons/autogen/c_meteo_glob_morsim.pxd +289 -0
  247. hydpy/cythons/autogen/c_meteo_glob_morsim.pyx +527 -0
  248. hydpy/cythons/autogen/c_meteo_precip_io.cp313-win_amd64.pyd +0 -0
  249. hydpy/cythons/autogen/c_meteo_precip_io.pxd +112 -0
  250. hydpy/cythons/autogen/c_meteo_precip_io.pyx +176 -0
  251. hydpy/cythons/autogen/c_meteo_psun_sun_glob_io.cp313-win_amd64.pyd +0 -0
  252. hydpy/cythons/autogen/c_meteo_psun_sun_glob_io.pxd +87 -0
  253. hydpy/cythons/autogen/c_meteo_psun_sun_glob_io.pyx +123 -0
  254. hydpy/cythons/autogen/c_meteo_sun_fao56.cp313-win_amd64.pyd +0 -0
  255. hydpy/cythons/autogen/c_meteo_sun_fao56.pxd +209 -0
  256. hydpy/cythons/autogen/c_meteo_sun_fao56.pyx +343 -0
  257. hydpy/cythons/autogen/c_meteo_sun_morsim.cp313-win_amd64.pyd +0 -0
  258. hydpy/cythons/autogen/c_meteo_sun_morsim.pxd +286 -0
  259. hydpy/cythons/autogen/c_meteo_sun_morsim.pyx +519 -0
  260. hydpy/cythons/autogen/c_meteo_temp_io.cp313-win_amd64.pyd +0 -0
  261. hydpy/cythons/autogen/c_meteo_temp_io.pxd +112 -0
  262. hydpy/cythons/autogen/c_meteo_temp_io.pyx +176 -0
  263. hydpy/cythons/autogen/c_musk.cp313-win_amd64.pyd +0 -0
  264. hydpy/cythons/autogen/c_musk.pxd +282 -0
  265. hydpy/cythons/autogen/c_musk.pyx +605 -0
  266. hydpy/cythons/autogen/c_musk_classic.cp313-win_amd64.pyd +0 -0
  267. hydpy/cythons/autogen/c_musk_classic.pxd +138 -0
  268. hydpy/cythons/autogen/c_musk_classic.pyx +226 -0
  269. hydpy/cythons/autogen/c_musk_mct.cp313-win_amd64.pyd +0 -0
  270. hydpy/cythons/autogen/c_musk_mct.pxd +282 -0
  271. hydpy/cythons/autogen/c_musk_mct.pyx +609 -0
  272. hydpy/cythons/autogen/c_rconc.cp313-win_amd64.pyd +0 -0
  273. hydpy/cythons/autogen/c_rconc.pxd +119 -0
  274. hydpy/cythons/autogen/c_rconc.pyx +174 -0
  275. hydpy/cythons/autogen/c_rconc_nash.cp313-win_amd64.pyd +0 -0
  276. hydpy/cythons/autogen/c_rconc_nash.pxd +111 -0
  277. hydpy/cythons/autogen/c_rconc_nash.pyx +185 -0
  278. hydpy/cythons/autogen/c_rconc_uh.cp313-win_amd64.pyd +0 -0
  279. hydpy/cythons/autogen/c_rconc_uh.pxd +92 -0
  280. hydpy/cythons/autogen/c_rconc_uh.pyx +125 -0
  281. hydpy/cythons/autogen/c_sw1d.cp313-win_amd64.pyd +0 -0
  282. hydpy/cythons/autogen/c_sw1d.pxd +511 -0
  283. hydpy/cythons/autogen/c_sw1d.pyx +1263 -0
  284. hydpy/cythons/autogen/c_sw1d_channel.cp313-win_amd64.pyd +0 -0
  285. hydpy/cythons/autogen/c_sw1d_channel.pxd +119 -0
  286. hydpy/cythons/autogen/c_sw1d_channel.pyx +300 -0
  287. hydpy/cythons/autogen/c_sw1d_gate_out.cp313-win_amd64.pyd +0 -0
  288. hydpy/cythons/autogen/c_sw1d_gate_out.pxd +240 -0
  289. hydpy/cythons/autogen/c_sw1d_gate_out.pyx +476 -0
  290. hydpy/cythons/autogen/c_sw1d_lias.cp313-win_amd64.pyd +0 -0
  291. hydpy/cythons/autogen/c_sw1d_lias.pxd +320 -0
  292. hydpy/cythons/autogen/c_sw1d_lias.pyx +619 -0
  293. hydpy/cythons/autogen/c_sw1d_lias_sluice.cp313-win_amd64.pyd +0 -0
  294. hydpy/cythons/autogen/c_sw1d_lias_sluice.pxd +325 -0
  295. hydpy/cythons/autogen/c_sw1d_lias_sluice.pyx +644 -0
  296. hydpy/cythons/autogen/c_sw1d_network.cp313-win_amd64.pyd +0 -0
  297. hydpy/cythons/autogen/c_sw1d_network.pxd +90 -0
  298. hydpy/cythons/autogen/c_sw1d_network.pyx +246 -0
  299. hydpy/cythons/autogen/c_sw1d_pump.cp313-win_amd64.pyd +0 -0
  300. hydpy/cythons/autogen/c_sw1d_pump.pxd +256 -0
  301. hydpy/cythons/autogen/c_sw1d_pump.pyx +502 -0
  302. hydpy/cythons/autogen/c_sw1d_q_in.cp313-win_amd64.pyd +0 -0
  303. hydpy/cythons/autogen/c_sw1d_q_in.pxd +224 -0
  304. hydpy/cythons/autogen/c_sw1d_q_in.pyx +383 -0
  305. hydpy/cythons/autogen/c_sw1d_q_out.cp313-win_amd64.pyd +0 -0
  306. hydpy/cythons/autogen/c_sw1d_q_out.pxd +224 -0
  307. hydpy/cythons/autogen/c_sw1d_q_out.pyx +383 -0
  308. hydpy/cythons/autogen/c_sw1d_storage.cp313-win_amd64.pyd +0 -0
  309. hydpy/cythons/autogen/c_sw1d_storage.pxd +193 -0
  310. hydpy/cythons/autogen/c_sw1d_storage.pyx +349 -0
  311. hydpy/cythons/autogen/c_sw1d_weir_out.cp313-win_amd64.pyd +0 -0
  312. hydpy/cythons/autogen/c_sw1d_weir_out.pxd +212 -0
  313. hydpy/cythons/autogen/c_sw1d_weir_out.pyx +404 -0
  314. hydpy/cythons/autogen/c_test.cp313-win_amd64.pyd +0 -0
  315. hydpy/cythons/autogen/c_test.pxd +175 -0
  316. hydpy/cythons/autogen/c_test.pyx +348 -0
  317. hydpy/cythons/autogen/c_test_discontinous.cp313-win_amd64.pyd +0 -0
  318. hydpy/cythons/autogen/c_test_discontinous.pxd +146 -0
  319. hydpy/cythons/autogen/c_test_discontinous.pyx +256 -0
  320. hydpy/cythons/autogen/c_test_stiff0d.cp313-win_amd64.pyd +0 -0
  321. hydpy/cythons/autogen/c_test_stiff0d.pxd +146 -0
  322. hydpy/cythons/autogen/c_test_stiff0d.pyx +250 -0
  323. hydpy/cythons/autogen/c_test_stiff1d.cp313-win_amd64.pyd +0 -0
  324. hydpy/cythons/autogen/c_test_stiff1d.pxd +145 -0
  325. hydpy/cythons/autogen/c_test_stiff1d.pyx +294 -0
  326. hydpy/cythons/autogen/c_whmod.cp313-win_amd64.pyd +0 -0
  327. hydpy/cythons/autogen/c_whmod.pxd +482 -0
  328. hydpy/cythons/autogen/c_whmod.pyx +1156 -0
  329. hydpy/cythons/autogen/c_whmod_rural.cp313-win_amd64.pyd +0 -0
  330. hydpy/cythons/autogen/c_whmod_rural.pxd +411 -0
  331. hydpy/cythons/autogen/c_whmod_rural.pyx +982 -0
  332. hydpy/cythons/autogen/c_whmod_urban.cp313-win_amd64.pyd +0 -0
  333. hydpy/cythons/autogen/c_whmod_urban.pxd +482 -0
  334. hydpy/cythons/autogen/c_whmod_urban.pyx +1155 -0
  335. hydpy/cythons/autogen/c_wland.cp313-win_amd64.pyd +0 -0
  336. hydpy/cythons/autogen/c_wland.pxd +842 -0
  337. hydpy/cythons/autogen/c_wland.pyx +1890 -0
  338. hydpy/cythons/autogen/c_wland_gd.cp313-win_amd64.pyd +0 -0
  339. hydpy/cythons/autogen/c_wland_gd.pxd +829 -0
  340. hydpy/cythons/autogen/c_wland_gd.pyx +1847 -0
  341. hydpy/cythons/autogen/c_wland_wag.cp313-win_amd64.pyd +0 -0
  342. hydpy/cythons/autogen/c_wland_wag.pxd +810 -0
  343. hydpy/cythons/autogen/c_wland_wag.pyx +1780 -0
  344. hydpy/cythons/autogen/c_wq.cp313-win_amd64.pyd +0 -0
  345. hydpy/cythons/autogen/c_wq.pxd +275 -0
  346. hydpy/cythons/autogen/c_wq.pyx +652 -0
  347. hydpy/cythons/autogen/c_wq_trapeze.cp313-win_amd64.pyd +0 -0
  348. hydpy/cythons/autogen/c_wq_trapeze.pxd +170 -0
  349. hydpy/cythons/autogen/c_wq_trapeze.pyx +400 -0
  350. hydpy/cythons/autogen/c_wq_trapeze_strickler.cp313-win_amd64.pyd +0 -0
  351. hydpy/cythons/autogen/c_wq_trapeze_strickler.pxd +243 -0
  352. hydpy/cythons/autogen/c_wq_trapeze_strickler.pyx +578 -0
  353. hydpy/cythons/autogen/c_wq_walrus.cp313-win_amd64.pyd +0 -0
  354. hydpy/cythons/autogen/c_wq_walrus.pxd +61 -0
  355. hydpy/cythons/autogen/c_wq_walrus.pyx +82 -0
  356. hydpy/cythons/autogen/configutils.cp313-win_amd64.pyd +0 -0
  357. hydpy/cythons/autogen/configutils.pxd +17 -0
  358. hydpy/cythons/autogen/configutils.pyx +119 -0
  359. hydpy/cythons/autogen/interfaceutils.cp313-win_amd64.pyd +0 -0
  360. hydpy/cythons/autogen/interfaceutils.pxd +31 -0
  361. hydpy/cythons/autogen/interfaceutils.pyx +82 -0
  362. hydpy/cythons/autogen/interputils.cp313-win_amd64.pyd +0 -0
  363. hydpy/cythons/autogen/interputils.pxd +42 -0
  364. hydpy/cythons/autogen/interputils.pyx +118 -0
  365. hydpy/cythons/autogen/masterinterface.cp313-win_amd64.pyd +0 -0
  366. hydpy/cythons/autogen/masterinterface.pxd +153 -0
  367. hydpy/cythons/autogen/masterinterface.pyx +222 -0
  368. hydpy/cythons/autogen/pointerutils.cp313-win_amd64.pyd +0 -0
  369. hydpy/cythons/autogen/pointerutils.pxd +31 -0
  370. hydpy/cythons/autogen/pointerutils.pyx +650 -0
  371. hydpy/cythons/autogen/ppolyutils.cp313-win_amd64.pyd +0 -0
  372. hydpy/cythons/autogen/ppolyutils.pxd +35 -0
  373. hydpy/cythons/autogen/ppolyutils.pyx +59 -0
  374. hydpy/cythons/autogen/quadutils.cp313-win_amd64.pyd +0 -0
  375. hydpy/cythons/autogen/quadutils.pxd +26 -0
  376. hydpy/cythons/autogen/quadutils.pyx +973 -0
  377. hydpy/cythons/autogen/rootutils.cp313-win_amd64.pyd +0 -0
  378. hydpy/cythons/autogen/rootutils.pxd +28 -0
  379. hydpy/cythons/autogen/rootutils.pyx +109 -0
  380. hydpy/cythons/autogen/sequenceutils.cp313-win_amd64.pyd +0 -0
  381. hydpy/cythons/autogen/sequenceutils.pxd +45 -0
  382. hydpy/cythons/autogen/sequenceutils.pyx +101 -0
  383. hydpy/cythons/autogen/smoothutils.cp313-win_amd64.pyd +0 -0
  384. hydpy/cythons/autogen/smoothutils.pxd +29 -0
  385. hydpy/cythons/autogen/smoothutils.pyx +833 -0
  386. hydpy/cythons/configutils.pxd +8 -0
  387. hydpy/cythons/configutils.pyi +5 -0
  388. hydpy/cythons/configutils.pyx +110 -0
  389. hydpy/cythons/interfaceutils.pxd +22 -0
  390. hydpy/cythons/interfaceutils.pyi +15 -0
  391. hydpy/cythons/interfaceutils.pyx +73 -0
  392. hydpy/cythons/interputils.pxd +33 -0
  393. hydpy/cythons/interputils.pyi +32 -0
  394. hydpy/cythons/interputils.pyx +109 -0
  395. hydpy/cythons/modelutils.py +2990 -0
  396. hydpy/cythons/pointerutils.pxd +22 -0
  397. hydpy/cythons/pointerutils.pyi +89 -0
  398. hydpy/cythons/pointerutils.pyx +641 -0
  399. hydpy/cythons/ppolyutils.pxd +26 -0
  400. hydpy/cythons/ppolyutils.pyi +21 -0
  401. hydpy/cythons/ppolyutils.pyx +50 -0
  402. hydpy/cythons/quadutils.pxd +17 -0
  403. hydpy/cythons/quadutils.pyi +13 -0
  404. hydpy/cythons/quadutils.pyx +964 -0
  405. hydpy/cythons/rootutils.pxd +19 -0
  406. hydpy/cythons/rootutils.pyi +21 -0
  407. hydpy/cythons/rootutils.pyx +100 -0
  408. hydpy/cythons/sequenceutils.pxd +36 -0
  409. hydpy/cythons/sequenceutils.pyi +7 -0
  410. hydpy/cythons/sequenceutils.pyx +92 -0
  411. hydpy/cythons/smoothutils.pxd +20 -0
  412. hydpy/cythons/smoothutils.pyi +15 -0
  413. hydpy/cythons/smoothutils.pyx +824 -0
  414. hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/land_dill_assl.py +13 -0
  415. hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/land_lahn_kalk.py +13 -0
  416. hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/land_lahn_leun.py +14 -0
  417. hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/land_lahn_marb.py +13 -0
  418. hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/stream_dill_assl_lahn_leun.py +5 -0
  419. hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/stream_lahn_leun_lahn_kalk.py +5 -0
  420. hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/stream_lahn_marb_lahn_leun.py +5 -0
  421. hydpy/data/HydPy-H-Lahn/control/default/land.py +9 -0
  422. hydpy/data/HydPy-H-Lahn/control/default/land_dill_assl.py +57 -0
  423. hydpy/data/HydPy-H-Lahn/control/default/land_lahn_kalk.py +57 -0
  424. hydpy/data/HydPy-H-Lahn/control/default/land_lahn_leun.py +56 -0
  425. hydpy/data/HydPy-H-Lahn/control/default/land_lahn_marb.py +57 -0
  426. hydpy/data/HydPy-H-Lahn/control/default/stream_dill_assl_lahn_leun.py +7 -0
  427. hydpy/data/HydPy-H-Lahn/control/default/stream_lahn_leun_lahn_kalk.py +7 -0
  428. hydpy/data/HydPy-H-Lahn/control/default/stream_lahn_marb_lahn_leun.py +7 -0
  429. hydpy/data/HydPy-H-Lahn/multiple_runs.xml +309 -0
  430. hydpy/data/HydPy-H-Lahn/multiple_runs_alpha.xml +71 -0
  431. hydpy/data/HydPy-H-Lahn/network/default/headwaters.py +11 -0
  432. hydpy/data/HydPy-H-Lahn/network/default/nonheadwaters.py +11 -0
  433. hydpy/data/HydPy-H-Lahn/network/default/streams.py +8 -0
  434. hydpy/data/HydPy-H-Lahn/series/default/dill_assl_obs_q.asc +11387 -0
  435. hydpy/data/HydPy-H-Lahn/series/default/evap_pet_hbv96_input_normalairtemperature.nc +0 -0
  436. hydpy/data/HydPy-H-Lahn/series/default/evap_pet_hbv96_input_normalevapotranspiration.nc +0 -0
  437. hydpy/data/HydPy-H-Lahn/series/default/hland_96_input_p.nc +0 -0
  438. hydpy/data/HydPy-H-Lahn/series/default/hland_96_input_t.nc +0 -0
  439. hydpy/data/HydPy-H-Lahn/series/default/lahn_kalk_obs_q.asc +11387 -0
  440. hydpy/data/HydPy-H-Lahn/series/default/lahn_leun_obs_q.asc +11387 -0
  441. hydpy/data/HydPy-H-Lahn/series/default/lahn_marb_obs_q.asc +11387 -0
  442. hydpy/data/HydPy-H-Lahn/series/default/land_dill_assl_evap_pet_hbv96_input_normalairtemperature.asc +11387 -0
  443. hydpy/data/HydPy-H-Lahn/series/default/land_dill_assl_evap_pet_hbv96_input_normalevapotranspiration.asc +11387 -0
  444. hydpy/data/HydPy-H-Lahn/series/default/land_dill_assl_hland_96_input_p.asc +11387 -0
  445. hydpy/data/HydPy-H-Lahn/series/default/land_dill_assl_hland_96_input_t.asc +11387 -0
  446. hydpy/data/HydPy-H-Lahn/series/default/land_lahn_kalk_evap_pet_hbv96_input_normalairtemperature.asc +11387 -0
  447. hydpy/data/HydPy-H-Lahn/series/default/land_lahn_kalk_evap_pet_hbv96_input_normalevapotranspiration.asc +11387 -0
  448. hydpy/data/HydPy-H-Lahn/series/default/land_lahn_kalk_hland_96_input_p.asc +11387 -0
  449. hydpy/data/HydPy-H-Lahn/series/default/land_lahn_kalk_hland_96_input_t.asc +11387 -0
  450. hydpy/data/HydPy-H-Lahn/series/default/land_lahn_leun_evap_pet_hbv96_input_normalairtemperature.asc +11387 -0
  451. hydpy/data/HydPy-H-Lahn/series/default/land_lahn_leun_evap_pet_hbv96_input_normalevapotranspiration.asc +11387 -0
  452. hydpy/data/HydPy-H-Lahn/series/default/land_lahn_leun_hland_96_input_p.asc +11387 -0
  453. hydpy/data/HydPy-H-Lahn/series/default/land_lahn_leun_hland_96_input_t.asc +11387 -0
  454. hydpy/data/HydPy-H-Lahn/series/default/land_lahn_marb_evap_pet_hbv96_input_normalairtemperature.asc +11387 -0
  455. hydpy/data/HydPy-H-Lahn/series/default/land_lahn_marb_evap_pet_hbv96_input_normalevapotranspiration.asc +11387 -0
  456. hydpy/data/HydPy-H-Lahn/series/default/land_lahn_marb_hland_96_input_p.asc +11387 -0
  457. hydpy/data/HydPy-H-Lahn/series/default/land_lahn_marb_hland_96_input_t.asc +11387 -0
  458. hydpy/data/HydPy-H-Lahn/series/default/obs_q.nc +0 -0
  459. hydpy/data/HydPy-H-Lahn/single_run.xml +152 -0
  460. hydpy/data/HydPy-H-Lahn/single_run.xmlt +143 -0
  461. hydpy/data/__init__.py +17 -0
  462. hydpy/docs/__init__.py +0 -0
  463. hydpy/docs/autofigs/__init__.py +0 -0
  464. hydpy/docs/bib/__init__.py +0 -0
  465. hydpy/docs/bib/refs.bib +566 -0
  466. hydpy/docs/combine_docversions.py +133 -0
  467. hydpy/docs/draw_model_sketches.py +1301 -0
  468. hydpy/docs/enable_autodoc.py +7 -0
  469. hydpy/docs/figs/HydPy-G-GR4.png +0 -0
  470. hydpy/docs/figs/HydPy-G-GR5.png +0 -0
  471. hydpy/docs/figs/HydPy-G-GR6.png +0 -0
  472. hydpy/docs/figs/HydPy-H-HBV96-COSERO.png +0 -0
  473. hydpy/docs/figs/HydPy-H-HBV96-PREVAH.png +0 -0
  474. hydpy/docs/figs/HydPy-H-HBV96.png +0 -0
  475. hydpy/docs/figs/HydPy-H-Lahn.png +0 -0
  476. hydpy/docs/figs/HydPy-KinW-Williams.png +0 -0
  477. hydpy/docs/figs/HydPy-L-DD.png +0 -0
  478. hydpy/docs/figs/HydPy-W-Wag.png +0 -0
  479. hydpy/docs/figs/HydPy_Logo.png +0 -0
  480. hydpy/docs/figs/HydPy_Logo_Text.png +0 -0
  481. hydpy/docs/figs/IDLE-editor.png +0 -0
  482. hydpy/docs/figs/IDLE-shell.png +0 -0
  483. hydpy/docs/figs/LAWA_river-basin-bumbers.png +0 -0
  484. hydpy/docs/figs/__init__.py +0 -0
  485. hydpy/docs/html_/__init__.py +0 -0
  486. hydpy/docs/polish_html.py +57 -0
  487. hydpy/docs/prepare.py +224 -0
  488. hydpy/docs/publish_docs.py +53 -0
  489. hydpy/docs/rst/HydPy-ARMA.rst +27 -0
  490. hydpy/docs/rst/HydPy-Conv.rst +22 -0
  491. hydpy/docs/rst/HydPy-Dam.rst +79 -0
  492. hydpy/docs/rst/HydPy-Dummy.rst +21 -0
  493. hydpy/docs/rst/HydPy-Evap.rst +26 -0
  494. hydpy/docs/rst/HydPy-Exch.rst +36 -0
  495. hydpy/docs/rst/HydPy-G.rst +40 -0
  496. hydpy/docs/rst/HydPy-GA.rst +34 -0
  497. hydpy/docs/rst/HydPy-H.rst +24 -0
  498. hydpy/docs/rst/HydPy-KinW.rst +32 -0
  499. hydpy/docs/rst/HydPy-L.rst +42 -0
  500. hydpy/docs/rst/HydPy-Meteo.rst +28 -0
  501. hydpy/docs/rst/HydPy-Musk.rst +21 -0
  502. hydpy/docs/rst/HydPy-Rconc.rst +17 -0
  503. hydpy/docs/rst/HydPy-SW1D.rst +49 -0
  504. hydpy/docs/rst/HydPy-Test.rst +19 -0
  505. hydpy/docs/rst/HydPy-W.rst +20 -0
  506. hydpy/docs/rst/HydPy-WHMod.rst +19 -0
  507. hydpy/docs/rst/HydPy-WQ.rst +20 -0
  508. hydpy/docs/rst/__init__.py +0 -0
  509. hydpy/docs/rst/additional_repositories.rst +40 -0
  510. hydpy/docs/rst/auxiliaries.rst +31 -0
  511. hydpy/docs/rst/continuous_integration.rst +75 -0
  512. hydpy/docs/rst/core.rst +75 -0
  513. hydpy/docs/rst/cythons.rst +47 -0
  514. hydpy/docs/rst/definitions.rst +506 -0
  515. hydpy/docs/rst/developer_guide.rst +54 -0
  516. hydpy/docs/rst/example_projects.rst +40 -0
  517. hydpy/docs/rst/execution.rst +22 -0
  518. hydpy/docs/rst/framework_tools.rst +56 -0
  519. hydpy/docs/rst/how_to_read_the_reference_manual.rst +156 -0
  520. hydpy/docs/rst/hydpydependencies.rst +55 -0
  521. hydpy/docs/rst/index.rst +125 -0
  522. hydpy/docs/rst/installation.rst +155 -0
  523. hydpy/docs/rst/model_families.rst +79 -0
  524. hydpy/docs/rst/model_overview.rst +291 -0
  525. hydpy/docs/rst/modelimports.rst +10 -0
  526. hydpy/docs/rst/options.rst +119 -0
  527. hydpy/docs/rst/programming_style.rst +572 -0
  528. hydpy/docs/rst/project_structure.rst +520 -0
  529. hydpy/docs/rst/quickstart.rst +304 -0
  530. hydpy/docs/rst/reference_manual.rst +29 -0
  531. hydpy/docs/rst/required_tools.rst +50 -0
  532. hydpy/docs/rst/simulation.rst +514 -0
  533. hydpy/docs/rst/submodel_interfaces.rst +32 -0
  534. hydpy/docs/rst/tests_and_documentation.rst +85 -0
  535. hydpy/docs/rst/user_guide.rst +38 -0
  536. hydpy/docs/rst/version_control.rst +116 -0
  537. hydpy/docs/rst/zbibliography.rst +8 -0
  538. hydpy/docs/sphinx/__init__.py +0 -0
  539. hydpy/docs/sphinx/_themes/basic_hydpy/changes/frameset.html +11 -0
  540. hydpy/docs/sphinx/_themes/basic_hydpy/changes/rstsource.html +15 -0
  541. hydpy/docs/sphinx/_themes/basic_hydpy/changes/versionchanges.html +33 -0
  542. hydpy/docs/sphinx/_themes/basic_hydpy/defindex.html +35 -0
  543. hydpy/docs/sphinx/_themes/basic_hydpy/domainindex.html +56 -0
  544. hydpy/docs/sphinx/_themes/basic_hydpy/genindex-single.html +63 -0
  545. hydpy/docs/sphinx/_themes/basic_hydpy/genindex-split.html +41 -0
  546. hydpy/docs/sphinx/_themes/basic_hydpy/genindex.html +76 -0
  547. hydpy/docs/sphinx/_themes/basic_hydpy/globaltoc.html +11 -0
  548. hydpy/docs/sphinx/_themes/basic_hydpy/layout.html +221 -0
  549. hydpy/docs/sphinx/_themes/basic_hydpy/localtoc.html +15 -0
  550. hydpy/docs/sphinx/_themes/basic_hydpy/opensearch.xml +13 -0
  551. hydpy/docs/sphinx/_themes/basic_hydpy/page.html +13 -0
  552. hydpy/docs/sphinx/_themes/basic_hydpy/relations.html +23 -0
  553. hydpy/docs/sphinx/_themes/basic_hydpy/search.html +65 -0
  554. hydpy/docs/sphinx/_themes/basic_hydpy/searchbox.html +21 -0
  555. hydpy/docs/sphinx/_themes/basic_hydpy/searchfield.html +23 -0
  556. hydpy/docs/sphinx/_themes/basic_hydpy/sourcelink.html +18 -0
  557. hydpy/docs/sphinx/_themes/basic_hydpy/static/basic.css_t +925 -0
  558. hydpy/docs/sphinx/_themes/basic_hydpy/static/doctools.js +156 -0
  559. hydpy/docs/sphinx/_themes/basic_hydpy/static/documentation_options.js_t +13 -0
  560. hydpy/docs/sphinx/_themes/basic_hydpy/static/file.png +0 -0
  561. hydpy/docs/sphinx/_themes/basic_hydpy/static/language_data.js_t +26 -0
  562. hydpy/docs/sphinx/_themes/basic_hydpy/static/minus.png +0 -0
  563. hydpy/docs/sphinx/_themes/basic_hydpy/static/plus.png +0 -0
  564. hydpy/docs/sphinx/_themes/basic_hydpy/static/searchtools.js +574 -0
  565. hydpy/docs/sphinx/_themes/basic_hydpy/static/sphinx_highlight.js +154 -0
  566. hydpy/docs/sphinx/_themes/basic_hydpy/theme.conf +16 -0
  567. hydpy/docs/sphinx/_themes/classic_hydpy/layout.html +23 -0
  568. hydpy/docs/sphinx/_themes/classic_hydpy/static/classic.css_t +358 -0
  569. hydpy/docs/sphinx/_themes/classic_hydpy/static/sidebar.js_t +72 -0
  570. hydpy/docs/sphinx/_themes/classic_hydpy/theme.conf +32 -0
  571. hydpy/docs/sphinx/conf.py +398 -0
  572. hydpy/docs/sphinx/defaultlinks_extension.py +36 -0
  573. hydpy/docs/sphinx/integrationtest_extension.py +104 -0
  574. hydpy/docs/sphinx/projectstructure_extension.py +58 -0
  575. hydpy/docs/sphinx/submodelgraph_extension.py +53 -0
  576. hydpy/exe/__init__.py +0 -0
  577. hydpy/exe/commandtools.py +651 -0
  578. hydpy/exe/hyd.py +277 -0
  579. hydpy/exe/modelimports.py +41 -0
  580. hydpy/exe/replacetools.py +216 -0
  581. hydpy/exe/servertools.py +2348 -0
  582. hydpy/exe/xmltools.py +3280 -0
  583. hydpy/interfaces/__init__.py +0 -0
  584. hydpy/interfaces/aetinterfaces.py +94 -0
  585. hydpy/interfaces/dischargeinterfaces.py +45 -0
  586. hydpy/interfaces/petinterfaces.py +117 -0
  587. hydpy/interfaces/precipinterfaces.py +42 -0
  588. hydpy/interfaces/radiationinterfaces.py +79 -0
  589. hydpy/interfaces/rconcinterfaces.py +30 -0
  590. hydpy/interfaces/routinginterfaces.py +324 -0
  591. hydpy/interfaces/soilinterfaces.py +96 -0
  592. hydpy/interfaces/stateinterfaces.py +98 -0
  593. hydpy/interfaces/tempinterfaces.py +46 -0
  594. hydpy/models/__init__.py +0 -0
  595. hydpy/models/arma/__init__.py +14 -0
  596. hydpy/models/arma/arma_control.py +383 -0
  597. hydpy/models/arma/arma_derived.py +204 -0
  598. hydpy/models/arma/arma_fluxes.py +41 -0
  599. hydpy/models/arma/arma_inlets.py +11 -0
  600. hydpy/models/arma/arma_logs.py +19 -0
  601. hydpy/models/arma/arma_model.py +461 -0
  602. hydpy/models/arma/arma_outlets.py +11 -0
  603. hydpy/models/arma_rimorido.py +381 -0
  604. hydpy/models/conv/__init__.py +12 -0
  605. hydpy/models/conv/conv_control.py +303 -0
  606. hydpy/models/conv/conv_derived.py +271 -0
  607. hydpy/models/conv/conv_fluxes.py +54 -0
  608. hydpy/models/conv/conv_inlets.py +11 -0
  609. hydpy/models/conv/conv_model.py +687 -0
  610. hydpy/models/conv/conv_outlets.py +11 -0
  611. hydpy/models/conv_idw.py +120 -0
  612. hydpy/models/conv_idw_ed.py +184 -0
  613. hydpy/models/conv_nn.py +112 -0
  614. hydpy/models/dam/__init__.py +16 -0
  615. hydpy/models/dam/dam_aides.py +17 -0
  616. hydpy/models/dam/dam_control.py +346 -0
  617. hydpy/models/dam/dam_derived.py +559 -0
  618. hydpy/models/dam/dam_factors.py +46 -0
  619. hydpy/models/dam/dam_fluxes.py +179 -0
  620. hydpy/models/dam/dam_inlets.py +29 -0
  621. hydpy/models/dam/dam_logs.py +52 -0
  622. hydpy/models/dam/dam_model.py +5011 -0
  623. hydpy/models/dam/dam_outlets.py +23 -0
  624. hydpy/models/dam/dam_receivers.py +41 -0
  625. hydpy/models/dam/dam_senders.py +23 -0
  626. hydpy/models/dam/dam_solver.py +75 -0
  627. hydpy/models/dam/dam_states.py +11 -0
  628. hydpy/models/dam_llake.py +499 -0
  629. hydpy/models/dam_lreservoir.py +548 -0
  630. hydpy/models/dam_lretention.py +343 -0
  631. hydpy/models/dam_pump.py +278 -0
  632. hydpy/models/dam_pump_sluice.py +339 -0
  633. hydpy/models/dam_sluice.py +319 -0
  634. hydpy/models/dam_v001.py +1127 -0
  635. hydpy/models/dam_v002.py +381 -0
  636. hydpy/models/dam_v003.py +422 -0
  637. hydpy/models/dam_v004.py +665 -0
  638. hydpy/models/dam_v005.py +479 -0
  639. hydpy/models/dummy/__init__.py +15 -0
  640. hydpy/models/dummy/dummy_control.py +22 -0
  641. hydpy/models/dummy/dummy_fluxes.py +11 -0
  642. hydpy/models/dummy/dummy_inlets.py +11 -0
  643. hydpy/models/dummy/dummy_inputs.py +41 -0
  644. hydpy/models/dummy/dummy_model.py +196 -0
  645. hydpy/models/dummy/dummy_outlets.py +11 -0
  646. hydpy/models/dummy_interceptedwater.py +85 -0
  647. hydpy/models/dummy_node2node.py +83 -0
  648. hydpy/models/dummy_snowalbedo.py +84 -0
  649. hydpy/models/dummy_snowcover.py +84 -0
  650. hydpy/models/dummy_snowycanopy.py +86 -0
  651. hydpy/models/dummy_soilwater.py +85 -0
  652. hydpy/models/evap/__init__.py +13 -0
  653. hydpy/models/evap/evap_control.py +354 -0
  654. hydpy/models/evap/evap_derived.py +236 -0
  655. hydpy/models/evap/evap_factors.py +188 -0
  656. hydpy/models/evap/evap_fixed.py +68 -0
  657. hydpy/models/evap/evap_fluxes.py +150 -0
  658. hydpy/models/evap/evap_inputs.py +54 -0
  659. hydpy/models/evap/evap_logs.py +91 -0
  660. hydpy/models/evap/evap_masks.py +48 -0
  661. hydpy/models/evap/evap_model.py +9170 -0
  662. hydpy/models/evap/evap_parameters.py +149 -0
  663. hydpy/models/evap/evap_sequences.py +32 -0
  664. hydpy/models/evap/evap_states.py +18 -0
  665. hydpy/models/evap_aet_hbv96.py +372 -0
  666. hydpy/models/evap_aet_minhas.py +331 -0
  667. hydpy/models/evap_aet_morsim.py +627 -0
  668. hydpy/models/evap_pet_ambav1.py +483 -0
  669. hydpy/models/evap_pet_hbv96.py +147 -0
  670. hydpy/models/evap_pet_m.py +94 -0
  671. hydpy/models/evap_pet_mlc.py +107 -0
  672. hydpy/models/evap_ret_fao56.py +265 -0
  673. hydpy/models/evap_ret_io.py +74 -0
  674. hydpy/models/evap_ret_tw2002.py +165 -0
  675. hydpy/models/exch/__init__.py +14 -0
  676. hydpy/models/exch/exch_control.py +262 -0
  677. hydpy/models/exch/exch_derived.py +36 -0
  678. hydpy/models/exch/exch_factors.py +26 -0
  679. hydpy/models/exch/exch_fluxes.py +48 -0
  680. hydpy/models/exch/exch_inlets.py +11 -0
  681. hydpy/models/exch/exch_logs.py +12 -0
  682. hydpy/models/exch/exch_model.py +451 -0
  683. hydpy/models/exch/exch_outlets.py +17 -0
  684. hydpy/models/exch/exch_receivers.py +17 -0
  685. hydpy/models/exch_branch_hbv96.py +186 -0
  686. hydpy/models/exch_waterlevel.py +73 -0
  687. hydpy/models/exch_weir_hbv96.py +609 -0
  688. hydpy/models/ga/__init__.py +14 -0
  689. hydpy/models/ga/ga_aides.py +17 -0
  690. hydpy/models/ga/ga_control.py +208 -0
  691. hydpy/models/ga/ga_derived.py +77 -0
  692. hydpy/models/ga/ga_fluxes.py +83 -0
  693. hydpy/models/ga/ga_inputs.py +26 -0
  694. hydpy/models/ga/ga_logs.py +17 -0
  695. hydpy/models/ga/ga_model.py +2952 -0
  696. hydpy/models/ga/ga_states.py +87 -0
  697. hydpy/models/ga_garto.py +1001 -0
  698. hydpy/models/ga_garto_submodel1.py +79 -0
  699. hydpy/models/gland/__init__.py +14 -0
  700. hydpy/models/gland/gland_control.py +90 -0
  701. hydpy/models/gland/gland_derived.py +113 -0
  702. hydpy/models/gland/gland_fluxes.py +137 -0
  703. hydpy/models/gland/gland_inputs.py +12 -0
  704. hydpy/models/gland/gland_model.py +1439 -0
  705. hydpy/models/gland/gland_outlets.py +11 -0
  706. hydpy/models/gland/gland_states.py +90 -0
  707. hydpy/models/gland_gr4.py +501 -0
  708. hydpy/models/gland_gr5.py +463 -0
  709. hydpy/models/gland_gr6.py +487 -0
  710. hydpy/models/hland/__init__.py +20 -0
  711. hydpy/models/hland/hland_aides.py +19 -0
  712. hydpy/models/hland/hland_constants.py +37 -0
  713. hydpy/models/hland/hland_control.py +1530 -0
  714. hydpy/models/hland/hland_derived.py +683 -0
  715. hydpy/models/hland/hland_factors.py +57 -0
  716. hydpy/models/hland/hland_fixed.py +42 -0
  717. hydpy/models/hland/hland_fluxes.py +279 -0
  718. hydpy/models/hland/hland_inputs.py +19 -0
  719. hydpy/models/hland/hland_masks.py +107 -0
  720. hydpy/models/hland/hland_model.py +4664 -0
  721. hydpy/models/hland/hland_outlets.py +11 -0
  722. hydpy/models/hland/hland_parameters.py +227 -0
  723. hydpy/models/hland/hland_sequences.py +382 -0
  724. hydpy/models/hland/hland_states.py +236 -0
  725. hydpy/models/hland_96.py +1812 -0
  726. hydpy/models/hland_96c.py +1196 -0
  727. hydpy/models/hland_96p.py +1204 -0
  728. hydpy/models/kinw/__init__.py +18 -0
  729. hydpy/models/kinw/kinw_aides.py +306 -0
  730. hydpy/models/kinw/kinw_control.py +270 -0
  731. hydpy/models/kinw/kinw_derived.py +197 -0
  732. hydpy/models/kinw/kinw_fixed.py +33 -0
  733. hydpy/models/kinw/kinw_fluxes.py +37 -0
  734. hydpy/models/kinw/kinw_inlets.py +11 -0
  735. hydpy/models/kinw/kinw_model.py +3026 -0
  736. hydpy/models/kinw/kinw_outlets.py +11 -0
  737. hydpy/models/kinw/kinw_solver.py +45 -0
  738. hydpy/models/kinw/kinw_states.py +17 -0
  739. hydpy/models/kinw_williams.py +1299 -0
  740. hydpy/models/kinw_williams_ext.py +768 -0
  741. hydpy/models/lland/__init__.py +42 -0
  742. hydpy/models/lland/lland_aides.py +38 -0
  743. hydpy/models/lland/lland_constants.py +88 -0
  744. hydpy/models/lland/lland_control.py +1329 -0
  745. hydpy/models/lland/lland_derived.py +380 -0
  746. hydpy/models/lland/lland_factors.py +18 -0
  747. hydpy/models/lland/lland_fixed.py +128 -0
  748. hydpy/models/lland/lland_fluxes.py +626 -0
  749. hydpy/models/lland/lland_inlets.py +12 -0
  750. hydpy/models/lland/lland_inputs.py +33 -0
  751. hydpy/models/lland/lland_logs.py +17 -0
  752. hydpy/models/lland/lland_masks.py +212 -0
  753. hydpy/models/lland/lland_model.py +7690 -0
  754. hydpy/models/lland/lland_outlets.py +12 -0
  755. hydpy/models/lland/lland_parameters.py +195 -0
  756. hydpy/models/lland/lland_sequences.py +67 -0
  757. hydpy/models/lland/lland_states.py +280 -0
  758. hydpy/models/lland_dd.py +2270 -0
  759. hydpy/models/lland_knauf.py +2156 -0
  760. hydpy/models/lland_knauf_ic.py +1920 -0
  761. hydpy/models/meteo/__init__.py +12 -0
  762. hydpy/models/meteo/meteo_control.py +154 -0
  763. hydpy/models/meteo/meteo_derived.py +159 -0
  764. hydpy/models/meteo/meteo_factors.py +88 -0
  765. hydpy/models/meteo/meteo_fixed.py +19 -0
  766. hydpy/models/meteo/meteo_fluxes.py +46 -0
  767. hydpy/models/meteo/meteo_inputs.py +47 -0
  768. hydpy/models/meteo/meteo_logs.py +30 -0
  769. hydpy/models/meteo/meteo_model.py +2904 -0
  770. hydpy/models/meteo/meteo_parameters.py +14 -0
  771. hydpy/models/meteo/meteo_sequences.py +22 -0
  772. hydpy/models/meteo_clear_glob_io.py +77 -0
  773. hydpy/models/meteo_glob_fao56.py +217 -0
  774. hydpy/models/meteo_glob_io.py +68 -0
  775. hydpy/models/meteo_glob_morsim.py +444 -0
  776. hydpy/models/meteo_precip_io.py +76 -0
  777. hydpy/models/meteo_psun_sun_glob_io.py +83 -0
  778. hydpy/models/meteo_sun_fao56.py +188 -0
  779. hydpy/models/meteo_sun_morsim.py +466 -0
  780. hydpy/models/meteo_temp_io.py +76 -0
  781. hydpy/models/musk/__init__.py +15 -0
  782. hydpy/models/musk/musk_control.py +328 -0
  783. hydpy/models/musk/musk_derived.py +32 -0
  784. hydpy/models/musk/musk_factors.py +53 -0
  785. hydpy/models/musk/musk_fluxes.py +24 -0
  786. hydpy/models/musk/musk_inlets.py +11 -0
  787. hydpy/models/musk/musk_masks.py +15 -0
  788. hydpy/models/musk/musk_model.py +838 -0
  789. hydpy/models/musk/musk_outlets.py +11 -0
  790. hydpy/models/musk/musk_sequences.py +88 -0
  791. hydpy/models/musk/musk_solver.py +68 -0
  792. hydpy/models/musk/musk_states.py +64 -0
  793. hydpy/models/musk_classic.py +228 -0
  794. hydpy/models/musk_mct.py +1247 -0
  795. hydpy/models/rconc/__init__.py +12 -0
  796. hydpy/models/rconc/rconc_control.py +473 -0
  797. hydpy/models/rconc/rconc_derived.py +76 -0
  798. hydpy/models/rconc/rconc_fluxes.py +19 -0
  799. hydpy/models/rconc/rconc_logs.py +74 -0
  800. hydpy/models/rconc/rconc_model.py +260 -0
  801. hydpy/models/rconc/rconc_states.py +11 -0
  802. hydpy/models/rconc_nash.py +48 -0
  803. hydpy/models/rconc_uh.py +53 -0
  804. hydpy/models/sw1d/__init__.py +17 -0
  805. hydpy/models/sw1d/sw1d_control.py +356 -0
  806. hydpy/models/sw1d/sw1d_derived.py +85 -0
  807. hydpy/models/sw1d/sw1d_factors.py +78 -0
  808. hydpy/models/sw1d/sw1d_fixed.py +12 -0
  809. hydpy/models/sw1d/sw1d_fluxes.py +55 -0
  810. hydpy/models/sw1d/sw1d_inlets.py +17 -0
  811. hydpy/models/sw1d/sw1d_model.py +3385 -0
  812. hydpy/models/sw1d/sw1d_outlets.py +11 -0
  813. hydpy/models/sw1d/sw1d_receivers.py +11 -0
  814. hydpy/models/sw1d/sw1d_senders.py +11 -0
  815. hydpy/models/sw1d/sw1d_states.py +23 -0
  816. hydpy/models/sw1d_channel.py +2051 -0
  817. hydpy/models/sw1d_gate_out.py +599 -0
  818. hydpy/models/sw1d_lias.py +105 -0
  819. hydpy/models/sw1d_lias_sluice.py +531 -0
  820. hydpy/models/sw1d_network.py +1219 -0
  821. hydpy/models/sw1d_pump.py +448 -0
  822. hydpy/models/sw1d_q_in.py +79 -0
  823. hydpy/models/sw1d_q_out.py +81 -0
  824. hydpy/models/sw1d_storage.py +78 -0
  825. hydpy/models/sw1d_weir_out.py +75 -0
  826. hydpy/models/test/__init__.py +14 -0
  827. hydpy/models/test/test_control.py +28 -0
  828. hydpy/models/test/test_fluxes.py +17 -0
  829. hydpy/models/test/test_model.py +201 -0
  830. hydpy/models/test/test_solver.py +48 -0
  831. hydpy/models/test/test_states.py +17 -0
  832. hydpy/models/test_discontinous.py +46 -0
  833. hydpy/models/test_stiff0d.py +47 -0
  834. hydpy/models/test_stiff1d.py +42 -0
  835. hydpy/models/whmod/__init__.py +21 -0
  836. hydpy/models/whmod/whmod_constants.py +77 -0
  837. hydpy/models/whmod/whmod_control.py +333 -0
  838. hydpy/models/whmod/whmod_derived.py +210 -0
  839. hydpy/models/whmod/whmod_factors.py +9 -0
  840. hydpy/models/whmod/whmod_fluxes.py +105 -0
  841. hydpy/models/whmod/whmod_inputs.py +15 -0
  842. hydpy/models/whmod/whmod_masks.py +178 -0
  843. hydpy/models/whmod/whmod_model.py +2091 -0
  844. hydpy/models/whmod/whmod_parameters.py +155 -0
  845. hydpy/models/whmod/whmod_sequences.py +193 -0
  846. hydpy/models/whmod/whmod_states.py +73 -0
  847. hydpy/models/whmod_rural.py +794 -0
  848. hydpy/models/whmod_urban.py +1011 -0
  849. hydpy/models/wland/__init__.py +43 -0
  850. hydpy/models/wland/wland_aides.py +55 -0
  851. hydpy/models/wland/wland_constants.py +103 -0
  852. hydpy/models/wland/wland_control.py +508 -0
  853. hydpy/models/wland/wland_derived.py +330 -0
  854. hydpy/models/wland/wland_factors.py +11 -0
  855. hydpy/models/wland/wland_fixed.py +12 -0
  856. hydpy/models/wland/wland_fluxes.py +166 -0
  857. hydpy/models/wland/wland_inputs.py +33 -0
  858. hydpy/models/wland/wland_masks.py +54 -0
  859. hydpy/models/wland/wland_model.py +3755 -0
  860. hydpy/models/wland/wland_outlets.py +11 -0
  861. hydpy/models/wland/wland_parameters.py +214 -0
  862. hydpy/models/wland/wland_sequences.py +108 -0
  863. hydpy/models/wland/wland_solver.py +45 -0
  864. hydpy/models/wland/wland_states.py +56 -0
  865. hydpy/models/wland_gd.py +888 -0
  866. hydpy/models/wland_wag.py +1244 -0
  867. hydpy/models/wq/__init__.py +14 -0
  868. hydpy/models/wq/wq_control.py +117 -0
  869. hydpy/models/wq/wq_derived.py +182 -0
  870. hydpy/models/wq/wq_factors.py +79 -0
  871. hydpy/models/wq/wq_fluxes.py +17 -0
  872. hydpy/models/wq/wq_model.py +1889 -0
  873. hydpy/models/wq_trapeze.py +168 -0
  874. hydpy/models/wq_trapeze_strickler.py +101 -0
  875. hydpy/models/wq_walrus.py +57 -0
  876. hydpy/py.typed +0 -0
  877. hydpy/tests/.coveragerc +22 -0
  878. hydpy/tests/__init__.py +0 -0
  879. hydpy/tests/check_consistency.py +32 -0
  880. hydpy/tests/hydpydoctestcustomize.pth +1 -0
  881. hydpy/tests/hydpydoctestcustomize.py +15 -0
  882. hydpy/tests/iotesting/__init__.py +0 -0
  883. hydpy/tests/run_doctests.py +233 -0
  884. hydpy-6.2.dev1.data/scripts/hyd.py +277 -0
  885. hydpy-6.2.dev1.dist-info/LICENSE +165 -0
  886. hydpy-6.2.dev1.dist-info/METADATA +163 -0
  887. hydpy-6.2.dev1.dist-info/RECORD +890 -0
  888. hydpy-6.2.dev1.dist-info/WHEEL +5 -0
  889. hydpy-6.2.dev1.dist-info/licenses_hydpy_installer.txt +42 -0
  890. hydpy-6.2.dev1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,3385 @@
1
+ # pylint: disable=missing-module-docstring
2
+
3
+ # import...
4
+ # ...from HydPy
5
+ from hydpy.core import importtools
6
+ from hydpy.core import modeltools
7
+ from hydpy.core.typingtools import *
8
+ from hydpy.cythons import modelutils
9
+ from hydpy.cythons import smoothutils
10
+ from hydpy.interfaces import routinginterfaces
11
+ from hydpy.models.sw1d import sw1d_control
12
+ from hydpy.models.sw1d import sw1d_derived
13
+ from hydpy.models.sw1d import sw1d_fixed
14
+ from hydpy.models.sw1d import sw1d_inlets
15
+ from hydpy.models.sw1d import sw1d_outlets
16
+ from hydpy.models.sw1d import sw1d_factors
17
+ from hydpy.models.sw1d import sw1d_fluxes
18
+ from hydpy.models.sw1d import sw1d_states
19
+ from hydpy.models.sw1d import sw1d_receivers
20
+ from hydpy.models.sw1d import sw1d_senders
21
+
22
+
23
+ # pick data from and pass data to link sequences
24
+
25
+ RoutingModels_V1_V2: TypeAlias = Union[
26
+ "routinginterfaces.RoutingModel_V1", "routinginterfaces.RoutingModel_V2"
27
+ ]
28
+ RoutingModels_V1_V2_V3: TypeAlias = Union[
29
+ "routinginterfaces.RoutingModel_V1",
30
+ "routinginterfaces.RoutingModel_V2",
31
+ "routinginterfaces.RoutingModel_V3",
32
+ ]
33
+ RoutingModels_V2_V3: TypeAlias = Union[
34
+ "routinginterfaces.RoutingModel_V2", "routinginterfaces.RoutingModel_V3"
35
+ ]
36
+
37
+
38
+ class Pick_Inflow_V1(modeltools.Method):
39
+ """Pick the longitudinal inflow from an arbitrary number of inlet sequences."""
40
+
41
+ REQUIREDSEQUENCES = (sw1d_inlets.LongQ,)
42
+ RESULTSEQUENCES = (sw1d_fluxes.Inflow,)
43
+
44
+ @staticmethod
45
+ def __call__(model: modeltools.Model) -> None:
46
+ inl = model.sequences.inlets.fastaccess
47
+ flu = model.sequences.fluxes.fastaccess
48
+ flu.inflow = 0.0
49
+ for i in range(inl.len_longq):
50
+ flu.inflow += inl.longq[i][0]
51
+
52
+
53
+ class Pick_Outflow_V1(modeltools.Method):
54
+ """Pick the longitudinal outflow from an arbitrary number of outlet sequences."""
55
+
56
+ REQUIREDSEQUENCES = (sw1d_outlets.LongQ,)
57
+ RESULTSEQUENCES = (sw1d_fluxes.Outflow,)
58
+
59
+ @staticmethod
60
+ def __call__(model: modeltools.Model) -> None:
61
+ out = model.sequences.outlets.fastaccess
62
+ flu = model.sequences.fluxes.fastaccess
63
+ flu.outflow = 0.0
64
+ for i in range(out.len_longq):
65
+ flu.outflow += out.longq[i][0]
66
+
67
+
68
+ class Pick_LateralFlow_V1(modeltools.Method):
69
+ """Pick the lateral inflow from an arbitrary number of inlet sequences."""
70
+
71
+ REQUIREDSEQUENCES = (sw1d_inlets.LatQ,)
72
+ RESULTSEQUENCES = (sw1d_fluxes.LateralFlow,)
73
+
74
+ @staticmethod
75
+ def __call__(model: modeltools.SegmentModel) -> None:
76
+ inl = model.sequences.inlets.fastaccess
77
+ flu = model.sequences.fluxes.fastaccess
78
+ flu.lateralflow = 0.0
79
+ for i in range(inl.len_latq):
80
+ flu.lateralflow += inl.latq[i][0]
81
+
82
+
83
+ class Pick_WaterLevelDownstream_V1(modeltools.Method):
84
+ """Pick the water level downstream from a receiver sequence."""
85
+
86
+ REQUIREDSEQUENCES = (sw1d_receivers.WaterLevel,)
87
+ RESULTSEQUENCES = (sw1d_factors.WaterLevelDownstream,)
88
+
89
+ @staticmethod
90
+ def __call__(model: modeltools.SegmentModel) -> None:
91
+ fac = model.sequences.factors.fastaccess
92
+ rec = model.sequences.receivers.fastaccess
93
+ fac.waterleveldownstream = rec.waterlevel[0]
94
+
95
+
96
+ class Pass_Discharge_V1(modeltools.Method):
97
+ """Pass the calculated average discharge of the current simulation step to an
98
+ arbitrary number of inlet or outlet sequences.
99
+
100
+ Basic equation:
101
+ :math:`QLong = DischargeVolume / Seconds`
102
+
103
+ In contrast to typical methods for passing data to nodes, |Pass_Discharge_V1| not
104
+ only passes data to outlet sequences but also to inlet sequences. This
105
+ functionality addresses the rare but allowed setting of a discharge calculating
106
+ routing model lying at the inlet position of a subchannel, which is necessary for
107
+ modelling branches.
108
+
109
+ Examples:
110
+
111
+ Without any node connection, |Pass_Discharge_V1| does nothing:
112
+
113
+ >>> from hydpy import Element, Nodes, prepare_model
114
+ >>> e1 = Element("e1")
115
+ >>> e1.model = prepare_model("sw1d_lias")
116
+ >>> e1.model.pass_discharge_v1()
117
+
118
+ If any connections exist, |Pass_Discharge_V1| updates all corresponding
119
+ sequences with the same average discharge value:
120
+
121
+ >>> ni, no1, no2 = Nodes("ni", "no1", "no2", defaultvariable="LongQ")
122
+ >>> ni.sequences.sim = 1.0
123
+ >>> no1.sequences.sim = 2.0
124
+ >>> no2.sequences.sim = 3.0
125
+ >>> e2 = Element("e2", inlets=ni, outlets=(no1, no2))
126
+ >>> e2.model = prepare_model("sw1d_lias")
127
+ >>> e2.model.parameters.derived.seconds(60.0)
128
+ >>> e2.model.sequences.fluxes.dischargevolume = 120.0
129
+ >>> e2.model.pass_discharge_v1()
130
+ >>> ni.sequences.sim
131
+ sim(3.0)
132
+ >>> no1.sequences.sim
133
+ sim(4.0)
134
+ >>> no2.sequences.sim
135
+ sim(5.0)
136
+
137
+ .. testsetup::
138
+
139
+ >>> from hydpy import Node
140
+ >>> Node.clear_all()
141
+ >>> Element.clear_all()
142
+ """
143
+
144
+ DERIVEDPARAMETERS = (sw1d_derived.Seconds,)
145
+ REQUIREDSEQUENCES = (sw1d_fluxes.DischargeVolume,)
146
+ RESULTSEQUENCES = (sw1d_inlets.LongQ, sw1d_outlets.LongQ)
147
+
148
+ @staticmethod
149
+ def __call__(model: modeltools.Model) -> None:
150
+ der = model.parameters.derived.fastaccess
151
+ inl = model.sequences.inlets.fastaccess
152
+ out = model.sequences.outlets.fastaccess
153
+ flu = model.sequences.fluxes.fastaccess
154
+ discharge: float = flu.dischargevolume / der.seconds
155
+ for i in range(inl.len_longq):
156
+ inl.longq[i][0] += discharge
157
+ for i in range(out.len_longq):
158
+ out.longq[i][0] += discharge
159
+
160
+
161
+ class Pass_WaterLevel_V1(modeltools.Method):
162
+ """Pass the calculated water level to an arbitrary number of sender sequences."""
163
+
164
+ REQUIREDSEQUENCES = (sw1d_factors.WaterLevel,)
165
+ RESULTSEQUENCES = (sw1d_senders.WaterLevel,)
166
+
167
+ @staticmethod
168
+ def __call__(model: modeltools.SegmentModel) -> None:
169
+ fac = model.sequences.factors.fastaccess
170
+ sen = model.sequences.senders.fastaccess
171
+ for i in range(sen.len_waterlevel):
172
+ sen.waterlevel[i][0] = fac.waterlevel
173
+
174
+
175
+ # calculation methods
176
+
177
+
178
+ class Trigger_Preprocessing_V1(modeltools.Method):
179
+ """Order all submodels following the |StorageModel_V1|, |RoutingModel_V1|,
180
+ |RoutingModel_V2|, or |RoutingModel_V3| interface to prepare all invariant data for
181
+ a new internal simulation step.
182
+
183
+ Example:
184
+
185
+ >>> from hydpy import Element, Node, prepare_model
186
+ >>> nlong = Node("nlong", variable="LongQ")
187
+ >>> nlat = Node("nlat", variable="LatQ")
188
+ >>> e = Element("e", inlets=(nlong, nlat))
189
+ >>> channel = prepare_model("sw1d_channel")
190
+ >>> channel.parameters.control.nmbsegments(1)
191
+ >>> with channel.add_routingmodel_v1("sw1d_q_in", position=0, update=False):
192
+ ... pass
193
+ >>> with channel.add_storagemodel_v1("sw1d_storage", position=0, update=False):
194
+ ... pass
195
+ >>> e.model = channel
196
+ >>> nlong.sequences.sim = 1.0
197
+ >>> nlat.sequences.sim = 2.0
198
+ >>> channel.trigger_preprocessing_v1()
199
+ >>> channel.routingmodels[0].sequences.fluxes.inflow
200
+ inflow(1.0)
201
+ >>> channel.storagemodels[0].sequences.fluxes.lateralflow
202
+ lateralflow(2.0)
203
+
204
+ .. testsetup::
205
+
206
+ >>> Node.clear_all()
207
+ >>> Element.clear_all()
208
+ """
209
+
210
+ SUBMODELINTERFACES = (
211
+ routinginterfaces.RoutingModel_V1,
212
+ routinginterfaces.RoutingModel_V2,
213
+ routinginterfaces.RoutingModel_V3,
214
+ routinginterfaces.StorageModel_V1,
215
+ )
216
+
217
+ @staticmethod
218
+ def __call__(model: modeltools.Model) -> None:
219
+ for i in range(model.routingmodels.number):
220
+ if model.routingmodels.typeids[i] in (1, 2, 3):
221
+ cast(
222
+ RoutingModels_V1_V2_V3, model.routingmodels.submodels[i]
223
+ ).perform_preprocessing()
224
+ for i in range(model.storagemodels.number):
225
+ if model.storagemodels.typeids[i] == 1:
226
+ cast(
227
+ routinginterfaces.StorageModel_V1, model.storagemodels.submodels[i]
228
+ ).perform_preprocessing()
229
+
230
+
231
+ class Trigger_Postprocessing_V1(modeltools.Method):
232
+ """Order all submodels following the |StorageModel_V1|, |RoutingModel_V1|,
233
+ |RoutingModel_V2|, or |RoutingModel_V3| interface to execute all tasks relevant at
234
+ the end of each external simulation step.
235
+
236
+ Example:
237
+
238
+ >>> from hydpy import Element, Node, prepare_model
239
+ >>> nw = Node("nw", variable="WaterLevel")
240
+ >>> e = Element("e", senders=nw)
241
+ >>> channel = prepare_model("sw1d_channel")
242
+ >>> channel.parameters.control.nmbsegments(1)
243
+ >>> with channel.add_routingmodel_v1("sw1d_q_in", position=0, update=False):
244
+ ... derived.seconds(60.0)
245
+ ... fluxes.inflow = 2.0
246
+ >>> with channel.add_storagemodel_v1("sw1d_storage", position=0, update=False):
247
+ ... factors.waterlevel = 2.0
248
+ >>> e.model = channel
249
+ >>> channel.trigger_postprocessing_v1()
250
+ >>> channel.routingmodels[0].sequences.fluxes.dischargevolume
251
+ dischargevolume(120.0)
252
+ >>> nw.sequences.sim
253
+ sim(2.0)
254
+
255
+ .. testsetup::
256
+
257
+ >>> Node.clear_all()
258
+ >>> Element.clear_all()
259
+ """
260
+
261
+ SUBMODELINTERFACES = (
262
+ routinginterfaces.RoutingModel_V1,
263
+ routinginterfaces.RoutingModel_V2,
264
+ routinginterfaces.RoutingModel_V3,
265
+ routinginterfaces.StorageModel_V1,
266
+ )
267
+
268
+ @staticmethod
269
+ def __call__(model: modeltools.Model) -> None:
270
+ for i in range(model.routingmodels.number):
271
+ if model.routingmodels.typeids[i] in (1, 2, 3):
272
+ cast(
273
+ RoutingModels_V1_V2_V3, model.routingmodels.submodels[i]
274
+ ).perform_postprocessing()
275
+ for i in range(model.storagemodels.number):
276
+ if model.storagemodels.typeids[i] == 1:
277
+ cast(
278
+ routinginterfaces.StorageModel_V1, model.storagemodels.submodels[i]
279
+ ).perform_postprocessing()
280
+
281
+
282
+ class Calc_MaxTimeStep_V1(modeltools.Method):
283
+ r"""Estimate the highest possible computation time step for which we can expect
284
+ stability for a central LIAS-like routing model.
285
+
286
+ Basic equation :cite:p:`ref-Bates2010`:
287
+ :math:`MaxTimeStep = TimeStepFactor \cdot
288
+ \frac{1000 \cdot LengthMin}{GravitationalAcceleration \cdot WaterDepth}`
289
+
290
+ Examples:
291
+
292
+ >>> from hydpy.models.sw1d import *
293
+ >>> parameterstep()
294
+ >>> timestepfactor(0.5)
295
+ >>> derived.lengthmin(2.0)
296
+ >>> factors.waterdepth = 4.0
297
+ >>> model.calc_maxtimestep_v1()
298
+ >>> factors.maxtimestep
299
+ maxtimestep(159.637714)
300
+
301
+ |Calc_MaxTimeStep_V1| handles the case of zero water depth by setting the
302
+ maximum time step to infinity:
303
+
304
+ >>> factors.waterdepth = 0.0
305
+ >>> model.calc_maxtimestep_v1()
306
+ >>> factors.maxtimestep
307
+ maxtimestep(inf)
308
+ """
309
+
310
+ CONTROLPARAMETERS = (sw1d_control.TimeStepFactor,)
311
+ DERIVEDPARAMETERS = (sw1d_derived.LengthMin,)
312
+ FIXEDPARAMETERS = (sw1d_fixed.GravitationalAcceleration,)
313
+ REQUIREDSEQUENCES = (sw1d_factors.WaterDepth,)
314
+ RESULTSEQUENCES = (sw1d_factors.MaxTimeStep,)
315
+
316
+ @staticmethod
317
+ def __call__(model: modeltools.Model) -> None:
318
+ con = model.parameters.control.fastaccess
319
+ der = model.parameters.derived.fastaccess
320
+ fix = model.parameters.fixed.fastaccess
321
+ fac = model.sequences.factors.fastaccess
322
+ if fac.waterdepth > 0.0:
323
+ fac.maxtimestep = (con.timestepfactor * 1000.0 * der.lengthmin) / (
324
+ fix.gravitationalacceleration * fac.waterdepth
325
+ ) ** 0.5
326
+ else:
327
+ fac.maxtimestep = modelutils.inf
328
+
329
+
330
+ class Calc_MaxTimeStep_V2(modeltools.Method):
331
+ r"""Estimate the highest possible computation time step for which we can expect
332
+ stability for an inflow-providing routing model.
333
+
334
+ Basic equation:
335
+ :math:`MaxTimeStep = TimeStepFactor \cdot
336
+ \frac{1000 \cdot LengthDownstream}{5 / 3 \cdot |Inflow| \cdot WettedArea}`
337
+
338
+ Examples:
339
+
340
+ >>> from hydpy.models.sw1d import *
341
+ >>> parameterstep()
342
+ >>> timestepfactor(0.5)
343
+ >>> lengthdownstream(2.0)
344
+ >>> factors.wettedarea = 5.0
345
+ >>> fluxes.inflow = 6.0
346
+ >>> model.calc_maxtimestep_v2()
347
+ >>> factors.maxtimestep
348
+ maxtimestep(500.0)
349
+
350
+ For zero inflow values, the computation time step needs no restriction:
351
+
352
+ >>> fluxes.inflow = 0.0
353
+ >>> model.calc_maxtimestep_v2()
354
+ >>> factors.maxtimestep
355
+ maxtimestep(inf)
356
+
357
+ To prevent zero division, |Calc_MaxTimeStep_V2| also sets the maximum time step
358
+ to infinity if there is no wetted area:
359
+
360
+ >>> fluxes.inflow = 6.0
361
+ >>> factors.wettedarea = 0.0
362
+ >>> model.calc_maxtimestep_v2()
363
+ >>> factors.maxtimestep
364
+ maxtimestep(inf)
365
+ """
366
+
367
+ CONTROLPARAMETERS = (sw1d_control.LengthDownstream, sw1d_control.TimeStepFactor)
368
+ REQUIREDSEQUENCES = (sw1d_fluxes.Inflow, sw1d_factors.WettedArea)
369
+ RESULTSEQUENCES = (sw1d_factors.MaxTimeStep,)
370
+
371
+ @staticmethod
372
+ def __call__(model: modeltools.Model) -> None:
373
+ con = model.parameters.control.fastaccess
374
+ fac = model.sequences.factors.fastaccess
375
+ flu = model.sequences.fluxes.fastaccess
376
+ if (flu.inflow != 0.0) and (fac.wettedarea > 0.0):
377
+ cel: float = modelutils.fabs(5.0 / 3.0 * flu.inflow / fac.wettedarea)
378
+ fac.maxtimestep = con.timestepfactor * 1000.0 * con.lengthdownstream / cel
379
+ else:
380
+ fac.maxtimestep = modelutils.inf
381
+
382
+
383
+ class Calc_MaxTimeStep_V3(modeltools.Method):
384
+ r"""Estimate the highest possible computation time step for which we can expect
385
+ stability for a weir-like routing model.
386
+
387
+ Basic equation:
388
+ .. math::
389
+ MaxTimeStep = f \cdot \frac{1000 \cdot l}{c\cdot \sqrt{2 \cdot g \cdot h}}
390
+ \\ \\
391
+ f = TimeStepFactor \\
392
+ l = LengthDownstream \\
393
+ c = FlowCoefficient \\
394
+ g = GravitationalAcceleration \\
395
+ h = WaterLevel - CrestHeight
396
+
397
+ Examples:
398
+
399
+ >>> from hydpy.models.sw1d import *
400
+ >>> parameterstep()
401
+ >>> crestheight(5.0)
402
+ >>> flowcoefficient(0.6)
403
+ >>> timestepfactor(0.5)
404
+ >>> lengthupstream(2.0)
405
+ >>> factors.waterlevel = 7.0
406
+ >>> model.calc_maxtimestep_v3()
407
+ >>> factors.maxtimestep
408
+ maxtimestep(266.062857)
409
+
410
+ For water levels equal to or below the crest height, the flow over the weir is
411
+ zero and thus cannot cause instability. Hence, |Calc_MaxTimeStep_V3| sets
412
+ |MaxTimeStep| to infinity in such cases:
413
+
414
+ >>> factors.waterlevel = 5.0
415
+ >>> model.calc_maxtimestep_v3()
416
+ >>> factors.maxtimestep
417
+ maxtimestep(inf)
418
+ >>> factors.waterlevel = 3.0
419
+ >>> model.calc_maxtimestep_v3()
420
+ >>> factors.maxtimestep
421
+ maxtimestep(inf)
422
+ """
423
+
424
+ CONTROLPARAMETERS = (
425
+ sw1d_control.LengthUpstream,
426
+ sw1d_control.TimeStepFactor,
427
+ sw1d_control.FlowCoefficient,
428
+ sw1d_control.CrestHeight,
429
+ )
430
+ FIXEDPARAMETERS = (sw1d_fixed.GravitationalAcceleration,)
431
+ REQUIREDSEQUENCES = (sw1d_factors.WaterLevel,)
432
+ RESULTSEQUENCES = (sw1d_factors.MaxTimeStep,)
433
+
434
+ @staticmethod
435
+ def __call__(model: modeltools.Model) -> None:
436
+ con = model.parameters.control.fastaccess
437
+ fix = model.parameters.fixed.fastaccess
438
+ fac = model.sequences.factors.fastaccess
439
+ h: float = fac.waterlevel - con.crestheight
440
+ if h > 0.0:
441
+ c: float = con.flowcoefficient
442
+ g: float = fix.gravitationalacceleration
443
+ cel: float = c * (2.0 * g * h) ** 0.5
444
+ fac.maxtimestep = con.timestepfactor * 1000.0 * con.lengthupstream / cel
445
+ else:
446
+ fac.maxtimestep = modelutils.inf
447
+
448
+
449
+ class Calc_MaxTimeStep_V4(modeltools.Method):
450
+ r"""Estimate the highest possible computation time step for which we can expect
451
+ stability for an outflow-providing routing model.
452
+
453
+ Basic equation:
454
+ :math:`MaxTimeStep = TimeStepFactor \cdot
455
+ \frac{1000 \cdot LengthUpstream}{5 / 3 \cdot |Outflow| \cdot WettedArea}`
456
+
457
+ Examples:
458
+
459
+ >>> from hydpy.models.sw1d import *
460
+ >>> parameterstep()
461
+ >>> timestepfactor(0.5)
462
+ >>> lengthupstream(2.0)
463
+ >>> factors.wettedarea = 5.0
464
+ >>> fluxes.outflow = 6.0
465
+ >>> model.calc_maxtimestep_v4()
466
+ >>> factors.maxtimestep
467
+ maxtimestep(500.0)
468
+
469
+ For zero outflow values, the computation time step needs no restriction:
470
+
471
+ >>> fluxes.outflow = 0.0
472
+ >>> model.calc_maxtimestep_v4()
473
+ >>> factors.maxtimestep
474
+ maxtimestep(inf)
475
+
476
+ To prevent zero division, |Calc_MaxTimeStep_V4| also sets the maximum time step
477
+ to infinity if there is no wetted area:
478
+
479
+ >>> fluxes.outflow = 6.0
480
+ >>> factors.wettedarea = 0.0
481
+ >>> model.calc_maxtimestep_v4()
482
+ >>> factors.maxtimestep
483
+ maxtimestep(inf)
484
+ """
485
+
486
+ CONTROLPARAMETERS = (sw1d_control.LengthUpstream, sw1d_control.TimeStepFactor)
487
+ REQUIREDSEQUENCES = (sw1d_fluxes.Outflow, sw1d_factors.WettedArea)
488
+ RESULTSEQUENCES = (sw1d_factors.MaxTimeStep,)
489
+
490
+ @staticmethod
491
+ def __call__(model: modeltools.Model) -> None:
492
+ con = model.parameters.control.fastaccess
493
+ fac = model.sequences.factors.fastaccess
494
+ flu = model.sequences.fluxes.fastaccess
495
+ if (flu.outflow != 0.0) and (fac.wettedarea > 0.0):
496
+ cel: float = modelutils.fabs(5.0 / 3.0 * flu.outflow / fac.wettedarea)
497
+ fac.maxtimestep = con.timestepfactor * 1000.0 * con.lengthupstream / cel
498
+ else:
499
+ fac.maxtimestep = modelutils.inf
500
+
501
+
502
+ class Calc_MaxTimeStep_V5(modeltools.Method):
503
+ r"""Estimate the highest possible computation time step for which we can expect
504
+ stability for a gate-like routing model.
505
+
506
+ Basic equation:
507
+ .. math::
508
+ MaxTimeStep = f \cdot \frac{1000 \cdot l}{c \cdot \big( min (h, \ l) - b \big)
509
+ \cdot \sqrt{2 \cdot g \cdot (l_u - l_d)}}
510
+ \\ \\
511
+ f = TimeStepFactor \\
512
+ c = FlowCoefficient \\
513
+ h = GateHeight \\
514
+ l = WaterLevel \\
515
+ l_u = WaterLevelUpstream \\
516
+ l_d = WaterLevelDownstream\\
517
+ b = BottomLevel \\
518
+ g = GravitationalAcceleration
519
+
520
+ Examples:
521
+
522
+ The following examples all correspond to selected ones of |Calc_Discharge_V3|.
523
+
524
+ The case of a submerged gate and downstream flow:
525
+
526
+ >>> from hydpy.models.sw1d import *
527
+ >>> parameterstep()
528
+ >>> bottomlevel(4.0)
529
+ >>> gateheight(6.0)
530
+ >>> flowcoefficient(0.6)
531
+ >>> lengthupstream(4.0)
532
+ >>> timestepfactor(0.5)
533
+ >>> factors.waterlevel = 8.0
534
+ >>> factors.waterlevelupstream = 9.0
535
+ >>> factors.waterleveldownstream = 7.0
536
+ >>> model.calc_maxtimestep_v5()
537
+ >>> factors.maxtimestep
538
+ maxtimestep(266.062857)
539
+
540
+ The case of a non-submerged gate and upstream flow:
541
+
542
+ >>> gateheight(8.0)
543
+ >>> factors.waterlevelupstream = 7.0
544
+ >>> factors.waterleveldownstream = 9.0
545
+ >>> model.calc_maxtimestep_v5()
546
+ >>> factors.maxtimestep
547
+ maxtimestep(133.031429)
548
+
549
+ The case of a negative effective gate opening with zero discharge:
550
+
551
+ >>> gateheight(0.0)
552
+ >>> factors.waterlevelupstream = 7.0
553
+ >>> factors.waterleveldownstream = 9.0
554
+ >>> model.calc_maxtimestep_v5()
555
+ >>> factors.maxtimestep
556
+ maxtimestep(inf)
557
+
558
+ The case of a controlled gate opening:
559
+
560
+ >>> def sluice(model) -> None:
561
+ ... con = model.parameters.control.fastaccess
562
+ ... fac = model.sequences.factors.fastaccess
563
+ ... if fac.waterlevelupstream < fac.waterleveldownstream:
564
+ ... con.gateheight = 4.0
565
+ ... else:
566
+ ... con.gateheight = 10.0
567
+ >>> gateheight(callback=sluice)
568
+ >>> factors.waterlevelupstream = 9.0
569
+ >>> factors.waterleveldownstream = 7.0
570
+ >>> model.calc_maxtimestep_v5()
571
+ >>> factors.maxtimestep
572
+ maxtimestep(133.031429)
573
+ >>> factors.waterlevelupstream = 7.0
574
+ >>> factors.waterleveldownstream = 9.0
575
+ >>> model.calc_maxtimestep_v5()
576
+ >>> factors.maxtimestep
577
+ maxtimestep(inf)
578
+ """
579
+
580
+ CONTROLPARAMETERS = (
581
+ sw1d_control.LengthUpstream,
582
+ sw1d_control.BottomLevel,
583
+ sw1d_control.GateHeight,
584
+ sw1d_control.FlowCoefficient,
585
+ sw1d_control.TimeStepFactor,
586
+ )
587
+ FIXEDPARAMETERS = (sw1d_fixed.GravitationalAcceleration,)
588
+ REQUIREDSEQUENCES = (
589
+ sw1d_factors.WaterLevel,
590
+ sw1d_factors.WaterLevelUpstream,
591
+ sw1d_factors.WaterLevelDownstream,
592
+ )
593
+ RESULTSEQUENCES = (sw1d_factors.MaxTimeStep,)
594
+
595
+ @staticmethod
596
+ def __call__(model: modeltools.Model) -> None:
597
+ con = model.parameters.control.fastaccess
598
+ fix = model.parameters.fixed.fastaccess
599
+ fac = model.sequences.factors.fastaccess
600
+ con.gateheight_callback(model)
601
+ h: float = min(con.gateheight, fac.waterlevel) - con.bottomlevel
602
+ if h > 0.0:
603
+ c: float = con.flowcoefficient
604
+ g: float = fix.gravitationalacceleration
605
+ lu: float = fac.waterlevelupstream
606
+ ld: float = fac.waterleveldownstream
607
+ cel: float = c * h * (2.0 * g * modelutils.fabs(lu - ld)) ** 0.5
608
+ fac.maxtimestep = con.timestepfactor * 1000.0 * con.lengthupstream / cel
609
+ else:
610
+ fac.maxtimestep = modelutils.inf
611
+
612
+
613
+ class Calc_MaxTimeStep_V6(modeltools.Method):
614
+ r"""Estimate the highest possible computation time step for which we can expect
615
+ stability for an inflow- and outflow-providing routing model.
616
+
617
+ Basic equation:
618
+ :math:`MaxTimeStep = TimeStepFactor \cdot
619
+ \frac{1000 \cdot LengthMin}{5 / 3 \cdot |Discharge| \cdot WettedArea}`
620
+
621
+ Examples:
622
+
623
+ >>> from hydpy.models.sw1d import *
624
+ >>> parameterstep()
625
+ >>> timestepfactor(0.5)
626
+ >>> derived.lengthmin(2.0)
627
+ >>> factors.wettedarea = 5.0
628
+ >>> states.discharge = -6.0
629
+ >>> model.calc_maxtimestep_v6()
630
+ >>> factors.maxtimestep
631
+ maxtimestep(500.0)
632
+
633
+ For zero outflow values, the computation time step needs no restriction:
634
+
635
+ >>> states.discharge = 0.0
636
+ >>> model.calc_maxtimestep_v6()
637
+ >>> factors.maxtimestep
638
+ maxtimestep(inf)
639
+
640
+ To prevent zero division, |Calc_MaxTimeStep_V4| also sets the maximum time step
641
+ to infinity if there is no wetted area:
642
+
643
+ >>> states.discharge = 6.0
644
+ >>> factors.wettedarea = 0.0
645
+ >>> model.calc_maxtimestep_v6()
646
+ >>> factors.maxtimestep
647
+ maxtimestep(inf)
648
+ """
649
+
650
+ CONTROLPARAMETERS = (sw1d_control.TimeStepFactor,)
651
+ DERIVEDPARAMETERS = (sw1d_derived.LengthMin,)
652
+ REQUIREDSEQUENCES = (sw1d_states.Discharge, sw1d_factors.WettedArea)
653
+ RESULTSEQUENCES = (sw1d_factors.MaxTimeStep,)
654
+
655
+ @staticmethod
656
+ def __call__(model: modeltools.Model) -> None:
657
+ con = model.parameters.control.fastaccess
658
+ der = model.parameters.derived.fastaccess
659
+ fac = model.sequences.factors.fastaccess
660
+ sta = model.sequences.states.fastaccess
661
+ if (sta.discharge != 0.0) and (fac.wettedarea > 0.0):
662
+ cel: float = modelutils.fabs(5.0 / 3.0 * sta.discharge / fac.wettedarea)
663
+ fac.maxtimestep = con.timestepfactor * 1000.0 * der.lengthmin / cel
664
+ else:
665
+ fac.maxtimestep = modelutils.inf
666
+
667
+
668
+ class Calc_MaxTimeSteps_V1(modeltools.Method):
669
+ """Order all submodels that follow the |RoutingModel_V1|, |RoutingModel_V2|, or
670
+ |RoutingModel_V3| interface to estimate the highest possible computation time step.
671
+
672
+ Example:
673
+
674
+ >>> from hydpy.models.sw1d_channel import *
675
+ >>> parameterstep()
676
+ >>> nmbsegments(2)
677
+ >>> with model.add_storagemodel_v1("sw1d_storage", position=0, update=False):
678
+ ... factors.waterlevel = 6.0
679
+ >>> with model.add_routingmodel_v2("sw1d_lias", position=1, update=False):
680
+ ... timestepfactor(0.5)
681
+ ... derived.weightupstream(0.5)
682
+ ... derived.lengthmin(2.0)
683
+ ... factors.waterdepth = 4.0
684
+ >>> with model.add_storagemodel_v1("sw1d_storage", position=1, update=False):
685
+ ... factors.waterlevel = 4.0
686
+ >>> model.calc_maxtimesteps_v1()
687
+ >>> model.routingmodels[1].sequences.factors.maxtimestep
688
+ maxtimestep(159.637714)
689
+ """
690
+
691
+ SUBMODELINTERFACES = (
692
+ routinginterfaces.RoutingModel_V1,
693
+ routinginterfaces.RoutingModel_V2,
694
+ routinginterfaces.RoutingModel_V3,
695
+ )
696
+
697
+ @staticmethod
698
+ def __call__(model: modeltools.Model) -> None:
699
+ for i in range(model.routingmodels.number):
700
+ if model.routingmodels.typeids[i] in (1, 2, 3):
701
+ cast(
702
+ RoutingModels_V1_V2_V3, model.routingmodels.submodels[i]
703
+ ).determine_maxtimestep()
704
+
705
+
706
+ class Calc_TimeStep_V1(modeltools.Method):
707
+ r"""Determine the computation time step for which we can expect stability for a
708
+ complete channel network.
709
+
710
+ Examples:
711
+
712
+ Usually, |Calc_TimeStep_V1| takes the minimum of the individual routing models'
713
+ |MaxTimeStep| estimates:
714
+
715
+ >>> from hydpy.models.sw1d_channel import *
716
+ >>> parameterstep()
717
+ >>> nmbsegments(2)
718
+ >>> with model.add_routingmodel_v2("sw1d_lias", position=0, update=False):
719
+ ... factors.maxtimestep = 6.0
720
+ >>> with model.add_routingmodel_v2("sw1d_lias", position=1, update=False):
721
+ ... factors.maxtimestep = 7.0
722
+ >>> model.timeleft = 7.0
723
+ >>> model.calc_timestep_v1()
724
+ >>> factors.timestep
725
+ timestep(6.0)
726
+ >>> from hydpy import round_
727
+ >>> round_(model.timeleft)
728
+ 1.0
729
+
730
+ When appropriate, the `timeleft` argument synchronises the end of the next
731
+ internal computation step with the end of the current external simulation step:
732
+
733
+ >>> model.timeleft = 5.0
734
+ >>> model.calc_timestep_v1()
735
+ >>> factors.timestep
736
+ timestep(5.0)
737
+ >>> round_(model.timeleft)
738
+ 0.0
739
+ """
740
+
741
+ SUBMODELINTERFACES = (
742
+ routinginterfaces.RoutingModel_V1,
743
+ routinginterfaces.RoutingModel_V2,
744
+ routinginterfaces.RoutingModel_V3,
745
+ )
746
+ RESULTSEQUENCES = (sw1d_factors.TimeStep,)
747
+
748
+ @staticmethod
749
+ def __call__(model: modeltools.SubstepModel) -> None:
750
+ fac = model.sequences.factors.fastaccess
751
+
752
+ fac.timestep = modelutils.inf
753
+ for i in range(model.routingmodels.number):
754
+ if model.routingmodels.typeids[i] in (1, 2, 3):
755
+ timestep: float = cast(
756
+ RoutingModels_V1_V2_V3, model.routingmodels.submodels[i]
757
+ ).get_maxtimestep()
758
+ fac.timestep = min(fac.timestep, timestep)
759
+ if fac.timestep < model.timeleft:
760
+ model.timeleft -= fac.timestep
761
+ else:
762
+ fac.timestep = model.timeleft
763
+ model.timeleft = 0.0
764
+
765
+
766
+ class Send_TimeStep_V1(modeltools.Method):
767
+ """Send the actual computation time step to all submodels following the
768
+ |StorageModel_V1|, |RoutingModel_V1|, |RoutingModel_V2|, or |RoutingModel_V3|
769
+ interface.
770
+
771
+ Example:
772
+
773
+ >>> from hydpy.models.sw1d_channel import *
774
+ >>> parameterstep()
775
+ >>> nmbsegments(1)
776
+ >>> with model.add_routingmodel_v2("sw1d_lias", position=0, update=False):
777
+ ... factors.maxtimestep = 6.0
778
+ >>> with model.add_storagemodel_v1("sw1d_storage", position=0, update=False):
779
+ ... factors.maxtimestep = 6.0
780
+ >>> factors.timestep = 5.0
781
+ >>> model.send_timestep_v1()
782
+ >>> model.routingmodels[0].sequences.factors.timestep
783
+ timestep(5.0)
784
+ >>> model.storagemodels[0].sequences.factors.timestep
785
+ timestep(5.0)
786
+ """
787
+
788
+ SUBMODELINTERFACES = (
789
+ routinginterfaces.RoutingModel_V1,
790
+ routinginterfaces.RoutingModel_V2,
791
+ routinginterfaces.RoutingModel_V3,
792
+ routinginterfaces.StorageModel_V1,
793
+ )
794
+ REQUIREDSEQUENCES = (sw1d_factors.TimeStep,)
795
+
796
+ @staticmethod
797
+ def __call__(model: modeltools.Model) -> None:
798
+ fac = model.sequences.factors.fastaccess
799
+
800
+ for i in range(model.routingmodels.number):
801
+ if model.routingmodels.typeids[i] in (1, 2, 3):
802
+ cast(
803
+ RoutingModels_V1_V2_V3, model.routingmodels.submodels[i]
804
+ ).set_timestep(fac.timestep)
805
+ for i in range(model.storagemodels.number):
806
+ if model.storagemodels.typeids[i] == 1:
807
+ cast(
808
+ routinginterfaces.StorageModel_V1, model.storagemodels.submodels[i]
809
+ ).set_timestep(fac.timestep)
810
+
811
+
812
+ class Calc_WaterLevelUpstream_V1(modeltools.Method):
813
+ """Query the water level from an upstream submodel that follows the
814
+ |StorageModel_V1| interface.
815
+
816
+ Example:
817
+
818
+ >>> from hydpy import prepare_model
819
+ >>> main, sub = prepare_model("sw1d"), prepare_model("sw1d_storage")
820
+ >>> sub.sequences.factors.waterlevel = 2.0
821
+ >>> main.storagemodelupstream = sub
822
+ >>> main.storagemodelupstream_typeid = 1
823
+ >>> main.calc_waterlevelupstream_v1()
824
+ >>> main.sequences.factors.waterlevelupstream
825
+ waterlevelupstream(2.0)
826
+ """
827
+
828
+ SUBMODELINTERFACES = (routinginterfaces.StorageModel_V1,)
829
+ RESULTSEQUENCES = (sw1d_factors.WaterLevelUpstream,)
830
+
831
+ @staticmethod
832
+ def __call__(model: modeltools.Model) -> None:
833
+ fac = model.sequences.factors.fastaccess
834
+ if model.storagemodelupstream_typeid == 1:
835
+ fac.waterlevelupstream = cast(
836
+ routinginterfaces.StorageModel_V1, model.storagemodelupstream
837
+ ).get_waterlevel()
838
+
839
+
840
+ class Calc_WaterLevelDownstream_V1(modeltools.Method):
841
+ """Query the water level from a downstream submodel that follows the
842
+ |StorageModel_V1| interface.
843
+
844
+ Example:
845
+
846
+ >>> from hydpy import prepare_model
847
+ >>> main, sub = prepare_model("sw1d"), prepare_model("sw1d_storage")
848
+ >>> sub.sequences.factors.waterlevel = 2.0
849
+ >>> main.storagemodeldownstream = sub
850
+ >>> main.storagemodeldownstream_typeid = 1
851
+ >>> main.calc_waterleveldownstream_v1()
852
+ >>> main.sequences.factors.waterleveldownstream
853
+ waterleveldownstream(2.0)
854
+ """
855
+
856
+ SUBMODELINTERFACES = (routinginterfaces.StorageModel_V1,)
857
+ RESULTSEQUENCES = (sw1d_factors.WaterLevelDownstream,)
858
+
859
+ @staticmethod
860
+ def __call__(model: modeltools.Model) -> None:
861
+ fac = model.sequences.factors.fastaccess
862
+ if model.storagemodeldownstream_typeid == 1:
863
+ fac.waterleveldownstream = cast(
864
+ routinginterfaces.StorageModel_V1, model.storagemodeldownstream
865
+ ).get_waterlevel()
866
+
867
+
868
+ class Calc_WaterVolumeUpstream_V1(modeltools.Method):
869
+ """Query the water volume from an upstream submodel that follows the
870
+ |StorageModel_V1| interface.
871
+
872
+ Example:
873
+
874
+ >>> from hydpy import prepare_model
875
+ >>> main, sub = prepare_model("sw1d"), prepare_model("sw1d_storage")
876
+ >>> sub.sequences.states.watervolume = 2.0
877
+ >>> main.storagemodelupstream = sub
878
+ >>> main.storagemodelupstream_typeid = 1
879
+ >>> main.calc_watervolumeupstream_v1()
880
+ >>> main.sequences.factors.watervolumeupstream
881
+ watervolumeupstream(2.0)
882
+ """
883
+
884
+ SUBMODELINTERFACES = (routinginterfaces.StorageModel_V1,)
885
+ RESULTSEQUENCES = (sw1d_factors.WaterVolumeUpstream,)
886
+
887
+ @staticmethod
888
+ def __call__(model: modeltools.Model) -> None:
889
+ fac = model.sequences.factors.fastaccess
890
+ if model.storagemodelupstream_typeid == 1:
891
+ fac.watervolumeupstream = cast(
892
+ routinginterfaces.StorageModel_V1, model.storagemodelupstream
893
+ ).get_watervolume()
894
+
895
+
896
+ class Calc_WaterVolumeDownstream_V1(modeltools.Method):
897
+ """Query the water volume from a downstream submodel that follows the
898
+ |StorageModel_V1| interface.
899
+
900
+ Example:
901
+
902
+ >>> from hydpy import prepare_model
903
+ >>> main, sub = prepare_model("sw1d"), prepare_model("sw1d_storage")
904
+ >>> sub.sequences.states.watervolume = 2.0
905
+ >>> main.storagemodeldownstream = sub
906
+ >>> main.storagemodeldownstream_typeid = 1
907
+ >>> main.calc_watervolumedownstream_v1()
908
+ >>> main.sequences.factors.watervolumedownstream
909
+ watervolumedownstream(2.0)
910
+ """
911
+
912
+ SUBMODELINTERFACES = (routinginterfaces.StorageModel_V1,)
913
+ RESULTSEQUENCES = (sw1d_factors.WaterVolumeDownstream,)
914
+
915
+ @staticmethod
916
+ def __call__(model: modeltools.Model) -> None:
917
+ fac = model.sequences.factors.fastaccess
918
+ if model.storagemodeldownstream_typeid == 1:
919
+ fac.watervolumedownstream = cast(
920
+ routinginterfaces.StorageModel_V1, model.storagemodeldownstream
921
+ ).get_watervolume()
922
+
923
+
924
+ class Calc_WaterLevel_V1(modeltools.Method):
925
+ r"""Interpolate the water level based on the water levels of the adjacent channel
926
+ segments.
927
+
928
+ Basic equation:
929
+ .. math::
930
+ WaterLevel =
931
+ \omega \cdot WaterLevelUpstream + (1 - \omega) \cdot WaterLevelDownstream
932
+ \\ \\
933
+ \omega = WeightUpstream
934
+
935
+ Example:
936
+
937
+ >>> from hydpy.models.sw1d import *
938
+ >>> parameterstep()
939
+ >>> derived.weightupstream(0.8)
940
+ >>> factors.waterlevelupstream = 3.0
941
+ >>> factors.waterleveldownstream = 1.0
942
+ >>> model.calc_waterlevel_v1()
943
+ >>> factors.waterlevel
944
+ waterlevel(2.6)
945
+ """
946
+
947
+ DERIVEDPARAMETERS = (sw1d_derived.WeightUpstream,)
948
+ REQUIREDSEQUENCES = (
949
+ sw1d_factors.WaterLevelUpstream,
950
+ sw1d_factors.WaterLevelDownstream,
951
+ )
952
+ RESULTSEQUENCES = (sw1d_factors.WaterLevel,)
953
+
954
+ @staticmethod
955
+ def __call__(model: modeltools.Model) -> None:
956
+ der = model.parameters.derived.fastaccess
957
+ fac = model.sequences.factors.fastaccess
958
+ w: float = der.weightupstream
959
+ fac.waterlevel = (
960
+ w * fac.waterlevelupstream + (1.0 - w) * fac.waterleveldownstream
961
+ )
962
+
963
+
964
+ class Calc_WaterLevel_V2(modeltools.Method):
965
+ r"""Take the water level from the downstream channel segment.
966
+
967
+ Basic equation:
968
+ :math:`WaterLevel = WaterLevelDownstream`
969
+
970
+ Example:
971
+
972
+ >>> from hydpy.models.sw1d import *
973
+ >>> parameterstep()
974
+ >>> factors.waterleveldownstream = 3.0
975
+ >>> model.calc_waterlevel_v2()
976
+ >>> factors.waterlevel
977
+ waterlevel(3.0)
978
+ """
979
+
980
+ REQUIREDSEQUENCES = (sw1d_factors.WaterLevelDownstream,)
981
+ RESULTSEQUENCES = (sw1d_factors.WaterLevel,)
982
+
983
+ @staticmethod
984
+ def __call__(model: modeltools.Model) -> None:
985
+ fac = model.sequences.factors.fastaccess
986
+ fac.waterlevel = fac.waterleveldownstream
987
+
988
+
989
+ class Calc_WaterLevel_V3(modeltools.Method):
990
+ r"""Take the water level from the upstream channel segment.
991
+
992
+ Basic equation:
993
+ :math:`WaterLevel = WaterLevelUpstream`
994
+
995
+ Example:
996
+
997
+ >>> from hydpy.models.sw1d import *
998
+ >>> parameterstep()
999
+ >>> factors.waterlevelupstream = 3.0
1000
+ >>> model.calc_waterlevel_v3()
1001
+ >>> factors.waterlevel
1002
+ waterlevel(3.0)
1003
+ """
1004
+
1005
+ REQUIREDSEQUENCES = (sw1d_factors.WaterLevelUpstream,)
1006
+ RESULTSEQUENCES = (sw1d_factors.WaterLevel,)
1007
+
1008
+ @staticmethod
1009
+ def __call__(model: modeltools.Model) -> None:
1010
+ fac = model.sequences.factors.fastaccess
1011
+ fac.waterlevel = fac.waterlevelupstream
1012
+
1013
+
1014
+ class Calc_WaterLevel_V4(modeltools.Method):
1015
+ """Average the upstream and the downstream water level.
1016
+
1017
+ Basic equation:
1018
+ :math:`WaterLevel = (WaterLevelUpstream + WaterLevelUpstream) / 2`
1019
+
1020
+ Example:
1021
+
1022
+ >>> from hydpy.models.sw1d import *
1023
+ >>> parameterstep()
1024
+ >>> factors.waterlevelupstream = 3.0
1025
+ >>> factors.waterleveldownstream = 1.0
1026
+ >>> model.calc_waterlevel_v4()
1027
+ >>> factors.waterlevel
1028
+ waterlevel(2.0)
1029
+ """
1030
+
1031
+ REQUIREDSEQUENCES = (
1032
+ sw1d_factors.WaterLevelUpstream,
1033
+ sw1d_factors.WaterLevelDownstream,
1034
+ )
1035
+ RESULTSEQUENCES = (sw1d_factors.WaterLevel,)
1036
+
1037
+ @staticmethod
1038
+ def __call__(model: modeltools.Model) -> None:
1039
+ fac = model.sequences.factors.fastaccess
1040
+ fac.waterlevel = (fac.waterlevelupstream + fac.waterleveldownstream) / 2.0
1041
+
1042
+
1043
+ class Calc_WaterDepth_WaterLevel_CrossSectionModel_V2(modeltools.Method):
1044
+ """Let a submodel that follows the |CrossSectionModel_V2| submodel interface
1045
+ calculate the water depth and level based on the current water volume."""
1046
+
1047
+ CONTROLPARAMETERS = (sw1d_control.Length,)
1048
+ REQUIREDSEQUENCES = (sw1d_states.WaterVolume,)
1049
+ RESULTSEQUENCES = (sw1d_factors.WaterDepth, sw1d_factors.WaterLevel)
1050
+
1051
+ @staticmethod
1052
+ def __call__(
1053
+ model: modeltools.Model, submodel: routinginterfaces.CrossSectionModel_V2
1054
+ ) -> None:
1055
+ con = model.parameters.control.fastaccess
1056
+ fac = model.sequences.factors.fastaccess
1057
+ sta = model.sequences.states.fastaccess
1058
+ submodel.use_wettedarea(sta.watervolume / con.length)
1059
+ fac.waterdepth = submodel.get_waterdepth()
1060
+ fac.waterlevel = submodel.get_waterlevel()
1061
+
1062
+
1063
+ class Calc_WaterDepth_WaterLevel_V1(modeltools.Method):
1064
+ """Let a submodel that follows the |CrossSectionModel_V2| submodel interface
1065
+ calculate the water depth and level based on the current water volume.
1066
+
1067
+ Example:
1068
+
1069
+ We use |wq_trapeze| as an example submodel and configure it so that a wetted
1070
+ area of 18 m² corresponds to water depth of 4 m and a water level of 5 m:
1071
+
1072
+ >>> from hydpy.models.sw1d_storage import *
1073
+ >>> parameterstep()
1074
+ >>> length(2.0)
1075
+ >>> with model.add_crosssection_v2("wq_trapeze"):
1076
+ ... nmbtrapezes(3)
1077
+ ... bottomlevels(1.0, 3.0, 4.0)
1078
+ ... bottomwidths(2.0, 0.0, 2.0)
1079
+ ... sideslopes(0.0, 2.0, 2.0)
1080
+ >>> states.watervolume = 36.0
1081
+ >>> model.calc_waterdepth_waterlevel_v1()
1082
+ >>> factors.waterdepth
1083
+ waterdepth(4.0)
1084
+ >>> factors.waterlevel
1085
+ waterlevel(5.0)
1086
+ """
1087
+
1088
+ SUBMETHODS = (Calc_WaterDepth_WaterLevel_CrossSectionModel_V2,)
1089
+ CONTROLPARAMETERS = (sw1d_control.Length,)
1090
+ REQUIREDSEQUENCES = (sw1d_states.WaterVolume,)
1091
+ RESULTSEQUENCES = (sw1d_factors.WaterDepth, sw1d_factors.WaterLevel)
1092
+
1093
+ @staticmethod
1094
+ def __call__(model: modeltools.Model) -> None:
1095
+ if model.crosssection_typeid == 2:
1096
+ model.calc_waterdepth_waterlevel_crosssectionmodel_v2(
1097
+ cast(routinginterfaces.CrossSectionModel_V2, model.crosssection)
1098
+ )
1099
+
1100
+
1101
+ class Calc_WaterDepth_WettedArea_CrossSectionModel_V2(modeltools.Method):
1102
+ """Let a submodel that follows the |CrossSectionModel_V2| submodel interface
1103
+ calculate the water depth and the wetted area based on the current water level."""
1104
+
1105
+ REQUIREDSEQUENCES = (sw1d_factors.WaterLevel,)
1106
+ RESULTSEQUENCES = (sw1d_factors.WaterDepth, sw1d_factors.WettedArea)
1107
+
1108
+ @staticmethod
1109
+ def __call__(
1110
+ model: modeltools.Model, submodel: routinginterfaces.CrossSectionModel_V2
1111
+ ) -> None:
1112
+ fac = model.sequences.factors.fastaccess
1113
+ submodel.use_waterlevel(fac.waterlevel)
1114
+ fac.waterdepth = submodel.get_waterdepth()
1115
+ fac.wettedarea = submodel.get_wettedarea()
1116
+
1117
+
1118
+ class Calc_WaterDepth_WettedArea_V1(modeltools.Method):
1119
+ """Let a submodel that follows the |CrossSectionModel_V2| submodel interface
1120
+ calculate the water depth and the wetted area based on the current water level.
1121
+
1122
+ Example:
1123
+
1124
+ We use |wq_trapeze| as an example submodel and configure it so that a water
1125
+ level of 5 m corresponds to a water depth of 4 m and a wetted area of 18 m²:
1126
+
1127
+ >>> from hydpy.models.sw1d_pump import *
1128
+ >>> parameterstep()
1129
+ >>> with model.add_crosssection_v2("wq_trapeze"):
1130
+ ... nmbtrapezes(3)
1131
+ ... bottomlevels(1.0, 3.0, 4.0)
1132
+ ... bottomwidths(2.0, 0.0, 2.0)
1133
+ ... sideslopes(0.0, 2.0, 2.0)
1134
+ >>> factors.waterlevel = 5.0
1135
+ >>> model.calc_waterdepth_wettedarea_v1()
1136
+ >>> factors.waterdepth
1137
+ waterdepth(4.0)
1138
+ >>> factors.wettedarea
1139
+ wettedarea(18.0)
1140
+ """
1141
+
1142
+ SUBMETHODS = (Calc_WaterDepth_WettedArea_CrossSectionModel_V2,)
1143
+ REQUIREDSEQUENCES = (sw1d_factors.WaterLevel,)
1144
+ RESULTSEQUENCES = (sw1d_factors.WaterDepth, sw1d_factors.WettedArea)
1145
+
1146
+ @staticmethod
1147
+ def __call__(model: modeltools.Model) -> None:
1148
+ if model.crosssection_typeid == 2:
1149
+ model.calc_waterdepth_wettedarea_crosssectionmodel_v2(
1150
+ cast(routinginterfaces.CrossSectionModel_V2, model.crosssection)
1151
+ )
1152
+
1153
+
1154
+ class Calc_WaterDepth_WettedArea_WettedPerimeter_CrossSectionModel_V2(
1155
+ modeltools.Method
1156
+ ):
1157
+ """Let a submodel that follows the |CrossSectionModel_V2| submodel interface
1158
+ calculate the water depth, the wetted area, and the wetted perimeter based on the
1159
+ current water level."""
1160
+
1161
+ REQUIREDSEQUENCES = (sw1d_factors.WaterLevel,)
1162
+ RESULTSEQUENCES = (
1163
+ sw1d_factors.WaterDepth,
1164
+ sw1d_factors.WettedArea,
1165
+ sw1d_factors.WettedPerimeter,
1166
+ )
1167
+
1168
+ @staticmethod
1169
+ def __call__(
1170
+ model: modeltools.Model, submodel: routinginterfaces.CrossSectionModel_V2
1171
+ ) -> None:
1172
+ fac = model.sequences.factors.fastaccess
1173
+ submodel.use_waterlevel(fac.waterlevel)
1174
+ fac.waterdepth = submodel.get_waterdepth()
1175
+ fac.wettedarea = submodel.get_wettedarea()
1176
+ fac.wettedperimeter = submodel.get_wettedperimeter()
1177
+
1178
+
1179
+ class Calc_WaterDepth_WettedArea_WettedPerimeter_V1(modeltools.Method):
1180
+ """Let a submodel that follows the |CrossSectionModel_V2| submodel interface
1181
+ calculate the water depth, the wetted area, and the wetted perimeter based on the
1182
+ current water level.
1183
+
1184
+ Example:
1185
+
1186
+ We use |wq_trapeze| as an example submodel and configure it so that a water
1187
+ level of 5 m corresponds to a water depth of 4 m, a wetted area of 18 m², and
1188
+ a wetted perimeter of nearly 23 m:
1189
+
1190
+ >>> from hydpy.models.sw1d_lias import *
1191
+ >>> parameterstep()
1192
+ >>> with model.add_crosssection_v2("wq_trapeze"):
1193
+ ... nmbtrapezes(3)
1194
+ ... bottomlevels(1.0, 3.0, 4.0)
1195
+ ... bottomwidths(2.0, 0.0, 2.0)
1196
+ ... sideslopes(0.0, 2.0, 2.0)
1197
+ >>> factors.waterlevel = 5.0
1198
+ >>> model.calc_waterdepth_wettedarea_wettedperimeter_v1()
1199
+ >>> factors.waterdepth
1200
+ waterdepth(4.0)
1201
+ >>> factors.wettedarea
1202
+ wettedarea(18.0)
1203
+ >>> factors.wettedperimeter
1204
+ wettedperimeter(22.944272)
1205
+ """
1206
+
1207
+ SUBMETHODS = (Calc_WaterDepth_WettedArea_WettedPerimeter_CrossSectionModel_V2,)
1208
+ REQUIREDSEQUENCES = (sw1d_factors.WaterLevel,)
1209
+ RESULTSEQUENCES = (
1210
+ sw1d_factors.WaterDepth,
1211
+ sw1d_factors.WettedArea,
1212
+ sw1d_factors.WettedPerimeter,
1213
+ )
1214
+
1215
+ @staticmethod
1216
+ def __call__(model: modeltools.Model) -> None:
1217
+ if model.crosssection_typeid == 2:
1218
+ model.calc_waterdepth_wettedarea_wettedperimeter_crosssectionmodel_v2(
1219
+ cast(routinginterfaces.CrossSectionModel_V2, model.crosssection)
1220
+ )
1221
+
1222
+
1223
+ class Calc_DischargeUpstream_V1(modeltools.Method):
1224
+ """Sum the (partial) discharge of all upstream routing submodels following the
1225
+ |RoutingModel_V1| or |RoutingModel_V2| interface.
1226
+
1227
+ Examples:
1228
+
1229
+ If there is no upstream model, |DischargeUpstream| is zero:
1230
+
1231
+ >>> from hydpy import prepare_model
1232
+ >>> c2 = prepare_model("sw1d_channel")
1233
+ >>> c2.parameters.control.nmbsegments(1)
1234
+ >>> with c2.add_storagemodel_v1("sw1d_storage", position=0, update=False):
1235
+ ... pass
1236
+ >>> with c2.add_routingmodel_v2("sw1d_lias", position=1, update=False) as r2:
1237
+ ... states.discharge = 5.0
1238
+ >>> r2.calc_dischargeupstream_v1()
1239
+ >>> r2.sequences.fluxes.dischargeupstream
1240
+ dischargeupstream(0.0)
1241
+
1242
+ Otherwise, |Calc_DischargeUpstream_V1| totals the individual (partial)
1243
+ discharge values:
1244
+
1245
+ >>> from hydpy import Element, Node
1246
+ >>> n012 = Node("n012", variable="LongQ")
1247
+ >>> e2 = Element("e2", inlets=n012)
1248
+ >>> e2.model = c2
1249
+ >>> e0, e1 = Element("e0", outlets=n012), Element("e1", outlets=n012)
1250
+ >>> for element, discharge in ((e0, 1.0), (e1, 3.0)):
1251
+ ... c = prepare_model("sw1d_channel")
1252
+ ... element.model = c
1253
+ ... c.parameters.control.nmbsegments(1)
1254
+ ... with c.add_storagemodel_v1("sw1d_storage", position=0, update=False):
1255
+ ... pass
1256
+ ... with c.add_routingmodel_v2("sw1d_lias", position=1, update=False):
1257
+ ... states.discharge = discharge
1258
+ >>> network = c2.couple_models(nodes=(n012,), elements=(e0, e1, e2))
1259
+ >>> r2.calc_dischargeupstream_v1()
1260
+ >>> r2.sequences.fluxes.dischargeupstream
1261
+ dischargeupstream(4.0)
1262
+
1263
+ .. testsetup::
1264
+
1265
+ >>> Node.clear_all()
1266
+ >>> Element.clear_all()
1267
+ """
1268
+
1269
+ SUBMODELINTERFACES = (
1270
+ routinginterfaces.RoutingModel_V1,
1271
+ routinginterfaces.RoutingModel_V2,
1272
+ )
1273
+ REQUIREDSEQUENCES = (sw1d_states.Discharge,)
1274
+ RESULTSEQUENCES = (sw1d_fluxes.DischargeUpstream,)
1275
+
1276
+ @staticmethod
1277
+ def __call__(model: modeltools.Model) -> None:
1278
+ flu = model.sequences.fluxes.fastaccess
1279
+ sta = model.sequences.states.fastaccess
1280
+
1281
+ flu.dischargeupstream = 0.0
1282
+ for i in range(model.routingmodelsupstream.number):
1283
+ if model.routingmodelsupstream.typeids[i] in (1, 2):
1284
+ flu.dischargeupstream += cast(
1285
+ RoutingModels_V1_V2, model.routingmodelsupstream.submodels[i]
1286
+ ).get_partialdischargeupstream(sta.discharge)
1287
+
1288
+
1289
+ class Calc_DischargeDownstream_V1(modeltools.Method):
1290
+ """Sum the (partial) discharge of all downstream routing submodels following the
1291
+ |RoutingModel_V2| or |RoutingModel_V3| interface.
1292
+
1293
+ Examples:
1294
+
1295
+ If there is no downstream model, |DischargeDownstream| is zero:
1296
+
1297
+ >>> from hydpy import prepare_model
1298
+ >>> c0 = prepare_model("sw1d_channel")
1299
+ >>> c0.parameters.control.nmbsegments(1)
1300
+ >>> with c0.add_routingmodel_v2("sw1d_lias", position=0, update=False) as r0:
1301
+ ... states.discharge = 5.0
1302
+ >>> with c0.add_storagemodel_v1("sw1d_storage", position=0, update=False):
1303
+ ... pass
1304
+ >>> r0.calc_dischargedownstream_v1()
1305
+ >>> r0.sequences.fluxes.dischargedownstream
1306
+ dischargedownstream(0.0)
1307
+
1308
+ Otherwise, |Calc_DischargeDownstream_V1| totals the individual (partial)
1309
+ discharge values:
1310
+
1311
+ >>> from hydpy import Element, Node
1312
+ >>> n012 = Node("n012", variable="LongQ")
1313
+ >>> e0 = Element("e0", outlets=n012)
1314
+ >>> e0.model = c0
1315
+ >>> e1, e2 = Element("e1", inlets=n012), Element("e2", inlets=n012)
1316
+ >>> for element, discharge in ((e1, 1.0), (e2, 3.0)):
1317
+ ... c = prepare_model("sw1d_channel")
1318
+ ... element.model = c
1319
+ ... c.parameters.control.nmbsegments(1)
1320
+ ... with c.add_routingmodel_v2("sw1d_lias", position=0, update=False):
1321
+ ... states.discharge = discharge
1322
+ ... with c.add_storagemodel_v1("sw1d_storage", position=0, update=False):
1323
+ ... pass
1324
+ >>> network = c0.couple_models(nodes=(n012,), elements=(e0, e1, e2))
1325
+ >>> r0.calc_dischargedownstream_v1()
1326
+ >>> r0.sequences.fluxes.dischargedownstream
1327
+ dischargedownstream(4.0)
1328
+
1329
+ .. testsetup::
1330
+
1331
+ >>> Node.clear_all()
1332
+ >>> Element.clear_all()
1333
+ """
1334
+
1335
+ SUBMODELINTERFACES = (
1336
+ routinginterfaces.RoutingModel_V2,
1337
+ routinginterfaces.RoutingModel_V3,
1338
+ )
1339
+ REQUIREDSEQUENCES = (sw1d_states.Discharge,)
1340
+ RESULTSEQUENCES = (sw1d_fluxes.DischargeDownstream,)
1341
+
1342
+ @staticmethod
1343
+ def __call__(model: modeltools.Model) -> None:
1344
+ flu = model.sequences.fluxes.fastaccess
1345
+ sta = model.sequences.states.fastaccess
1346
+
1347
+ flu.dischargedownstream = 0.0
1348
+ for i in range(model.routingmodelsdownstream.number):
1349
+ if model.routingmodelsdownstream.typeids[i] in (2, 3):
1350
+ flu.dischargedownstream += cast(
1351
+ RoutingModels_V2_V3, model.routingmodelsdownstream.submodels[i]
1352
+ ).get_partialdischargedownstream(sta.discharge)
1353
+
1354
+
1355
+ class Calc_Discharge_V1(modeltools.Method):
1356
+ r"""Calculate the discharge according to :cite:t:`ref-Bates2010` and
1357
+ :cite:t:`ref-Almeida2012`.
1358
+
1359
+ Basic equation :cite:p:`ref-Almeida2012`:
1360
+ .. math::
1361
+ Q_{i-1/2}^{n+1} = \frac{\left[ (1-\theta) \cdot Q_{i-1/2}^n +
1362
+ \frac{\theta}{2} \cdot \left( Q_{i-3/2}^n + Q_{i+1/2}^n\right) \right] +
1363
+ g \cdot A_f \cdot \Delta t^n \cdot (y_{i-1}^n - y_i^n) / \Delta x}
1364
+ {1 + g \cdot \Delta t \cdot k_{st}^{-2} \cdot \left| Q_{i-1/2}^n \right|
1365
+ \cdot {P_f^n}^{\frac{4}{3}} \cdot {A_f^n}^{-\frac{7}{3}}}
1366
+ \\ \\
1367
+ Q = Discharge \\
1368
+ \theta = DiffusionFactor \\
1369
+ g = GravitationalAcceleration \\
1370
+ A_f = WettedArea \\
1371
+ \Delta t = TimeStep \\
1372
+ \Delta x = Length \\
1373
+ y = WaterLevel \\
1374
+ k_{st} = StricklerCoefficient \\
1375
+ P_f = WettedPerimeter
1376
+
1377
+ Examples:
1378
+
1379
+ The following channel configuration corresponds to a rectangular profile and
1380
+ a water surface slope of one meter per kilometre:
1381
+
1382
+ >>> from hydpy.models.sw1d import *
1383
+ >>> parameterstep()
1384
+ >>> diffusionfactor(0.2)
1385
+ >>> stricklercoefficient(50.0)
1386
+ >>> derived.lengthmean(2.0)
1387
+ >>> factors.timestep = 100.0
1388
+ >>> factors.wettedarea = 6.0
1389
+ >>> factors.wettedperimeter = 8.0
1390
+ >>> factors.waterlevelupstream = 5.0
1391
+ >>> factors.waterleveldownstream = 3.0
1392
+
1393
+ According to the Manning-Strickler equation, this configuration corresponds to
1394
+ a discharge of about 8 m³/s:
1395
+
1396
+ >>> dh = factors.waterlevelupstream - factors.waterleveldownstream
1397
+ >>> i = dh/ (1000.0 * derived.lengthmean)
1398
+ >>> r = factors.wettedarea / factors.wettedperimeter
1399
+ >>> v = stricklercoefficient * r**(2.0/3.0) * i**0.5
1400
+ >>> q = factors.wettedarea * v
1401
+ >>> from hydpy import round_
1402
+ >>> round_(q)
1403
+ 7.831208
1404
+
1405
+ If we use this value as the "old" discharge, relevant for the local inertial
1406
+ term, |Calc_Discharge_V1| calculates the same value as the "new" discharge,
1407
+ demonstrating its agreement with Manning-Stricker for stationary conditions:
1408
+
1409
+ >>> fluxes.dischargeupstream = q
1410
+ >>> fluxes.dischargedownstream = q
1411
+ >>> states.discharge = q
1412
+ >>> model.calc_discharge_v1()
1413
+ >>> states.discharge
1414
+ discharge(7.831208)
1415
+
1416
+ Reversing the surface water slope and the "old" discharge reverses the "new"
1417
+ discharge:
1418
+
1419
+ >>> factors.waterlevelupstream = -5.0
1420
+ >>> factors.waterleveldownstream = -3.0
1421
+ >>> fluxes.dischargeupstream = -q
1422
+ >>> fluxes.dischargedownstream = -q
1423
+ >>> states.discharge = -q
1424
+ >>> model.calc_discharge_v1()
1425
+ >>> states.discharge
1426
+ discharge(-7.831208)
1427
+
1428
+ With zero initial discharge, the estimated discharge becomes smaller:
1429
+
1430
+ >>> factors.waterlevelupstream = 5.0
1431
+ >>> factors.waterleveldownstream = 3.0
1432
+ >>> fluxes.dischargeupstream = 0.0
1433
+ >>> fluxes.dischargedownstream = 0.0
1434
+ >>> states.discharge = 0.0
1435
+ >>> model.calc_discharge_v1()
1436
+ >>> states.discharge
1437
+ discharge(5.886)
1438
+
1439
+ For differences between the initial discharge at the upstream, the actual, and
1440
+ the downstream position, the extension introduced by :cite:t:`ref-Almeida2012`
1441
+ to increase computational stability via numerical diffusion becomes relevant:
1442
+
1443
+ >>> states.discharge = q
1444
+ >>> model.calc_discharge_v1()
1445
+ >>> states.discharge
1446
+ discharge(6.937035)
1447
+
1448
+ |Calc_Discharge_V1| sets the discharge directly to zero for zero wetted
1449
+ cross-section areas to prevent zero division errors:
1450
+
1451
+ >>> factors.wettedarea = 0.0
1452
+ >>> model.calc_discharge_v1()
1453
+ >>> states.discharge
1454
+ discharge(0.0)
1455
+ """
1456
+
1457
+ CONTROLPARAMETERS = (
1458
+ sw1d_control.DiffusionFactor,
1459
+ sw1d_control.StricklerCoefficient,
1460
+ )
1461
+ DERIVEDPARAMETERS = (sw1d_derived.LengthMean,)
1462
+ FIXEDPARAMETERS = (sw1d_fixed.GravitationalAcceleration,)
1463
+ REQUIREDSEQUENCES = (
1464
+ sw1d_factors.TimeStep,
1465
+ sw1d_factors.WettedArea,
1466
+ sw1d_factors.WettedPerimeter,
1467
+ sw1d_factors.WaterLevelUpstream,
1468
+ sw1d_factors.WaterLevelDownstream,
1469
+ sw1d_fluxes.DischargeUpstream,
1470
+ sw1d_fluxes.DischargeDownstream,
1471
+ )
1472
+ UPDATEDSEQUENCES = (sw1d_states.Discharge,)
1473
+
1474
+ @staticmethod
1475
+ def __call__(model: modeltools.Model) -> None:
1476
+ con = model.parameters.control.fastaccess
1477
+ der = model.parameters.derived.fastaccess
1478
+ fix = model.parameters.fixed.fastaccess
1479
+ fac = model.sequences.factors.fastaccess
1480
+ flu = model.sequences.fluxes.fastaccess
1481
+ sta = model.sequences.states.fastaccess
1482
+
1483
+ if fac.wettedarea > 0.0:
1484
+ w: float = con.diffusionfactor # * fac.timestep / der.seconds
1485
+ nominator1: float = (1.0 - w) * sta.discharge + w / 2.0 * (
1486
+ flu.dischargeupstream + flu.dischargedownstream
1487
+ )
1488
+ nominator2: float = (
1489
+ fix.gravitationalacceleration
1490
+ * fac.wettedarea
1491
+ * fac.timestep
1492
+ * (fac.waterlevelupstream - fac.waterleveldownstream)
1493
+ / (1000.0 * der.lengthmean)
1494
+ )
1495
+ denominator: float = 1.0 + (
1496
+ fix.gravitationalacceleration
1497
+ * fac.timestep
1498
+ / con.stricklercoefficient**2.0
1499
+ * modelutils.fabs(sta.discharge)
1500
+ * fac.wettedperimeter ** (4.0 / 3.0)
1501
+ / fac.wettedarea ** (7.0 / 3.0)
1502
+ )
1503
+ sta.discharge = (nominator1 + nominator2) / denominator
1504
+ else:
1505
+ sta.discharge = 0.0
1506
+
1507
+
1508
+ class Calc_Discharge_V2(modeltools.Method):
1509
+ r"""Calculate the free weir flow after Poleni.
1510
+
1511
+ Basic equation:
1512
+ .. math::
1513
+ Q = w \cdot 2 / 3 \cdot c \cdot \sqrt{2 \cdot g} \cdot h^{3/2}
1514
+ \\ \\
1515
+ w = CrestWidth \\
1516
+ c = FlowCoefficient \\
1517
+ g = GravitationalAcceleration \\
1518
+ h = max(WaterLevel - CrestHeight, \ 0)
1519
+
1520
+ Examples:
1521
+
1522
+ >>> from hydpy.models.sw1d import *
1523
+ >>> parameterstep()
1524
+ >>> crestwidth(10.0)
1525
+ >>> crestheight(5.0)
1526
+ >>> flowcoefficient(0.6)
1527
+ >>> factors.waterlevel = 7.0
1528
+ >>> model.calc_discharge_v2()
1529
+ >>> states.discharge
1530
+ discharge(50.113471)
1531
+
1532
+ >>> factors.waterlevel = 4.0
1533
+ >>> model.calc_discharge_v2()
1534
+ >>> states.discharge
1535
+ discharge(0.0)
1536
+
1537
+ >>> factors.waterlevel = 5.0
1538
+ >>> model.calc_discharge_v2()
1539
+ >>> states.discharge
1540
+ discharge(0.0)
1541
+ """
1542
+
1543
+ CONTROLPARAMETERS = (
1544
+ sw1d_control.CrestHeight,
1545
+ sw1d_control.CrestWidth,
1546
+ sw1d_control.FlowCoefficient,
1547
+ )
1548
+ FIXEDPARAMETERS = (sw1d_fixed.GravitationalAcceleration,)
1549
+ REQUIREDSEQUENCES = (sw1d_factors.WaterLevel,)
1550
+ UPDATEDSEQUENCES = (sw1d_states.Discharge,)
1551
+
1552
+ @staticmethod
1553
+ def __call__(model: modeltools.Model) -> None:
1554
+ con = model.parameters.control.fastaccess
1555
+ fix = model.parameters.fixed.fastaccess
1556
+ fac = model.sequences.factors.fastaccess
1557
+ sta = model.sequences.states.fastaccess
1558
+ h: float = fac.waterlevel - con.crestheight
1559
+ if h > 0.0:
1560
+ w: float = con.crestwidth
1561
+ c: float = con.flowcoefficient
1562
+ g: float = fix.gravitationalacceleration
1563
+ sta.discharge = w * 2.0 / 3.0 * c * (2.0 * g) ** 0.5 * h ** (3.0 / 2.0)
1564
+ else:
1565
+ sta.discharge = 0.0
1566
+
1567
+
1568
+ class Calc_Discharge_V3(modeltools.Method):
1569
+ r"""Calculate the flow under a gate.
1570
+
1571
+ Basic equation:
1572
+ .. math::
1573
+ Q = d \cdot w \cdot c \cdot \big( min (h, \ l) - b \big)
1574
+ \cdot \sqrt{2 \cdot g \cdot (l_u - l_d)}
1575
+ \\ \\
1576
+ d = f_{filter\_norm}(l_u, \ l_d, \ DampingRadius) \\
1577
+ w = GateWidth \\
1578
+ c = FlowCoefficient \\
1579
+ h = GateHeight \\
1580
+ l = WaterLevel \\
1581
+ l_u = WaterLevelUpstream \\
1582
+ l_d = WaterLevelDownstream\\
1583
+ b = BottomLevel \\
1584
+ g = GravitationalAcceleration
1585
+
1586
+ Examples:
1587
+
1588
+ The first two examples deal with flow under a submerged gate:
1589
+
1590
+ >>> from hydpy.models.sw1d import *
1591
+ >>> parameterstep()
1592
+ >>> bottomlevel(4.0)
1593
+ >>> gateheight(6.0)
1594
+ >>> gatewidth(3.0)
1595
+ >>> flowcoefficient(0.6)
1596
+ >>> dampingradius(0.0)
1597
+ >>> factors.waterlevel = 8.0
1598
+ >>> factors.waterlevelupstream = 9.0
1599
+ >>> factors.waterleveldownstream = 7.0
1600
+ >>> model.calc_discharge_v3()
1601
+ >>> states.discharge
1602
+ discharge(22.551062)
1603
+ >>> factors.waterlevelupstream = 7.0
1604
+ >>> factors.waterleveldownstream = 9.0
1605
+ >>> model.calc_discharge_v3()
1606
+ >>> states.discharge
1607
+ discharge(-22.551062)
1608
+
1609
+ The next two examples deal with a gate submerge "on one side":
1610
+
1611
+ >>> gateheight(8.0)
1612
+ >>> factors.waterlevelupstream = 9.0
1613
+ >>> factors.waterleveldownstream = 7.0
1614
+ >>> model.calc_discharge_v3()
1615
+ >>> states.discharge
1616
+ discharge(45.102124)
1617
+ >>> factors.waterlevelupstream = 7.0
1618
+ >>> factors.waterleveldownstream = 9.0
1619
+ >>> model.calc_discharge_v3()
1620
+ >>> states.discharge
1621
+ discharge(-45.102124)
1622
+
1623
+ For non-submerged gates, the water level becomes the effective gate opening:
1624
+
1625
+ >>> gateheight(10.0)
1626
+ >>> factors.waterlevelupstream = 9.0
1627
+ >>> factors.waterleveldownstream = 7.0
1628
+ >>> model.calc_discharge_v3()
1629
+ >>> states.discharge
1630
+ discharge(45.102124)
1631
+ >>> factors.waterlevelupstream = 7.0
1632
+ >>> factors.waterleveldownstream = 9.0
1633
+ >>> model.calc_discharge_v3()
1634
+ >>> states.discharge
1635
+ discharge(-45.102124)
1636
+
1637
+ Negative effective gate openings result in zero discharge values:
1638
+
1639
+ >>> gateheight(0.0)
1640
+ >>> factors.waterlevelupstream = 9.0
1641
+ >>> factors.waterleveldownstream = 7.0
1642
+ >>> model.calc_discharge_v3()
1643
+ >>> states.discharge
1644
+ discharge(0.0)
1645
+ >>> factors.waterlevelupstream = 7.0
1646
+ >>> factors.waterleveldownstream = 9.0
1647
+ >>> model.calc_discharge_v3()
1648
+ >>> states.discharge
1649
+ discharge(0.0)
1650
+
1651
+ According to the given base equation, the change in flow rate with respect to
1652
+ changes in the water level gradient is highest for little water level
1653
+ gradients. For nearly zero gradients, these changes are so extreme that
1654
+ numerically solving this ordinary differential equation in combination with the
1655
+ ones of other routing models may introduce considerable artificial
1656
+ oscillations.
1657
+
1658
+ In the following example, a water level gradient of 1 mm corresponds to a
1659
+ discharge of only 0.3 m³/s, but also to a discharge increase of nearly
1660
+ 1600 m³/s per meter rise of the upstream water level:
1661
+
1662
+ >>> gateheight(10.0)
1663
+ >>> factors.waterlevelupstream = 8.0001
1664
+ >>> factors.waterleveldownstream = 8.0
1665
+ >>> model.calc_discharge_v3()
1666
+ >>> states.discharge
1667
+ discharge(0.31892)
1668
+ >>> from hydpy import NumericalDifferentiator, round_
1669
+ >>> numdiff = NumericalDifferentiator(
1670
+ ... xsequence=factors.waterlevelupstream,
1671
+ ... ysequences=[states.discharge],
1672
+ ... methods=[model.calc_discharge_v3])
1673
+ >>> numdiff()
1674
+ d_discharge/d_waterlevelupstream: 1594.591021
1675
+
1676
+ Principally, one could reduce the resulting oscillations by decreasing the
1677
+ internal calculation step size. However, this alone sometimes results in
1678
+ unacceptable increases in computation time. Hence, we suggest using the
1679
+ |DampingRadius| parameter to prevent such oscillations. Setting it, for
1680
+ example, to 1 mm reduces the change in discharge to 40 m³/s per meter:
1681
+
1682
+ >>> dampingradius(0.001)
1683
+ >>> numdiff()
1684
+ d_discharge/d_waterlevelupstream: 39.685825
1685
+
1686
+ Be careful not to set larger values than necessary, as this stabilisation trick
1687
+ does not only reduce the discharge derivative but also the discharge itself:
1688
+
1689
+ >>> model.calc_discharge_v3()
1690
+ >>> states.discharge
1691
+ discharge(0.001591)
1692
+
1693
+ All of the above examples deal with fixed gate openings. However, in reality,
1694
+ gates are often controlled, so their opening degree depends on other
1695
+ properties. Therefore, parameter |GateHeight| alternatively accepts a callback
1696
+ function for adjusting its values based on the current model state. One can,
1697
+ for example, define a "sluice" function that prevents any flow for reversed
1698
+ water level gradients:
1699
+
1700
+ >>> def sluice(model) -> None:
1701
+ ... con = model.parameters.control.fastaccess
1702
+ ... fac = model.sequences.factors.fastaccess
1703
+ ... if fac.waterlevelupstream < fac.waterleveldownstream:
1704
+ ... con.gateheight = 4.0
1705
+ ... else:
1706
+ ... con.gateheight = 10.0
1707
+ >>> ();gateheight(callback=sluice);() # doctest: +ELLIPSIS
1708
+ (...)
1709
+
1710
+ Method |Calc_Discharge_V3| applies this callback function before performing its
1711
+ further calculations. Hence, the following results agree with the
1712
+ "non-submerged gates" example for a positive water level gradient and the
1713
+ "negative effective gate opening" example for a negative one:
1714
+
1715
+ >>> factors.waterlevelupstream = 9.0
1716
+ >>> factors.waterleveldownstream = 7.0
1717
+ >>> model.calc_discharge_v3()
1718
+ >>> states.discharge
1719
+ discharge(45.102124)
1720
+ >>> factors.waterlevelupstream = 7.0
1721
+ >>> factors.waterleveldownstream = 9.0
1722
+ >>> model.calc_discharge_v3()
1723
+ >>> states.discharge
1724
+ discharge(0.0)
1725
+ """
1726
+
1727
+ CONTROLPARAMETERS = (
1728
+ sw1d_control.BottomLevel,
1729
+ sw1d_control.GateWidth,
1730
+ sw1d_control.GateHeight,
1731
+ sw1d_control.FlowCoefficient,
1732
+ sw1d_control.DampingRadius,
1733
+ )
1734
+ FIXEDPARAMETERS = (sw1d_fixed.GravitationalAcceleration,)
1735
+ REQUIREDSEQUENCES = (
1736
+ sw1d_factors.WaterLevel,
1737
+ sw1d_factors.WaterLevelUpstream,
1738
+ sw1d_factors.WaterLevelDownstream,
1739
+ )
1740
+ UPDATEDSEQUENCES = (sw1d_states.Discharge,)
1741
+
1742
+ @staticmethod
1743
+ def __call__(model: modeltools.Model) -> None:
1744
+ con = model.parameters.control.fastaccess
1745
+ fix = model.parameters.fixed.fastaccess
1746
+ fac = model.sequences.factors.fastaccess
1747
+ sta = model.sequences.states.fastaccess
1748
+
1749
+ con.gateheight_callback(model)
1750
+ h: float = min(con.gateheight, fac.waterlevel) - con.bottomlevel
1751
+ if h > 0.0:
1752
+ w: float = con.gatewidth
1753
+ c: float = con.flowcoefficient
1754
+ g: float = fix.gravitationalacceleration
1755
+ lu: float = fac.waterlevelupstream
1756
+ ld: float = fac.waterleveldownstream
1757
+ if ld < lu:
1758
+ sta.discharge = w * c * h * (2.0 * g * (lu - ld)) ** 0.5
1759
+ else:
1760
+ sta.discharge = -w * c * h * (2.0 * g * (ld - lu)) ** 0.5
1761
+ sta.discharge *= 1.0 - smoothutils.filter_norm(lu, ld, con.dampingradius)
1762
+ else:
1763
+ sta.discharge = 0.0
1764
+
1765
+
1766
+ class Calc_Discharge_V4(modeltools.Method):
1767
+ r"""Calculate the pumping rate.
1768
+
1769
+ Basic equation:
1770
+ .. math::
1771
+ Basic equations:
1772
+ .. math::
1773
+ Discharge = \begin{cases}
1774
+ 0 &|\ h_u < t_1 \\
1775
+ Q^* \cdot \frac{h_u - t_1}{t_2 - t_1}
1776
+ &|\ t_1 \leq h_u < t_2 \\
1777
+ Q^* &|\ t_2 \leq h_u
1778
+ \end{cases}
1779
+ \\ \\ \\
1780
+ Q^* = max \big( f_{gradient2pumpingrate}(h_d - h_u), \ 0 \big) \\
1781
+ h_u = WaterLevelUpstream \\
1782
+ h_d = WaterLevelDownstream \\
1783
+ t_1 = TargetWaterLevel1 \\
1784
+ t_2 = TargetWaterLevel2
1785
+
1786
+ Examples:
1787
+
1788
+ The maximum pumping rate is 1 m³/s for equal water levels and decreases
1789
+ linearly with rising downstream water levels until it reaches 0 m³/s:
1790
+
1791
+ >>> from hydpy.models.sw1d import *
1792
+ >>> parameterstep()
1793
+ >>> gradient2pumpingrate(PPoly(Poly(x0=0.0, cs=[1.0, -0.1]),
1794
+ ... Poly(x0=10.0, cs=[0.0])))
1795
+
1796
+ We prepare a |UnitTest| object to demonstrate how |Calc_Discharge_V4| behaves
1797
+ when the upstream water level changes:
1798
+
1799
+ >>> from hydpy import UnitTest
1800
+ >>> test = UnitTest(
1801
+ ... model, model.calc_discharge_v4,
1802
+ ... last_example=7,
1803
+ ... parseqs=(factors.waterlevelupstream, states.discharge))
1804
+
1805
+ We fix the downstream water level to 2 m and vary the upstream water level
1806
+ between 1.5 m to 4.5 m:
1807
+
1808
+ >>> factors.waterleveldownstream = 2.0
1809
+ >>> test.nexts.waterlevelupstream = 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5
1810
+
1811
+ If we set both target water levels to the same value, the pump becomes fully
1812
+ activated or deactivated when the upstream water level exceeds or falls below
1813
+ this threshold:
1814
+
1815
+ >>> targetwaterlevel1(2.0)
1816
+ >>> targetwaterlevel2(2.0)
1817
+ >>> test()
1818
+ | ex. | waterlevelupstream | discharge |
1819
+ ----------------------------------------
1820
+ | 1 | 1.5 | 0.0 |
1821
+ | 2 | 2.0 | 1.0 |
1822
+ | 3 | 2.5 | 0.95 |
1823
+ | 4 | 3.0 | 0.9 |
1824
+ | 5 | 3.5 | 0.85 |
1825
+ | 6 | 4.0 | 0.8 |
1826
+ | 7 | 4.5 | 0.75 |
1827
+
1828
+ Setting |TargetWaterLevel1| and |TargetWaterLevel2| to the same value might
1829
+ result in situations with frequent "on-off switching", which may eventually
1830
+ have adverse effects on computational efficiency or simulation accuracy. After
1831
+ setting |TargetWaterLevel2| to 4 m, the pump's transition between on and off
1832
+ becomes smoother:
1833
+
1834
+ >>> targetwaterlevel2(4.0)
1835
+ >>> test()
1836
+ | ex. | waterlevelupstream | discharge |
1837
+ ----------------------------------------
1838
+ | 1 | 1.5 | 0.0 |
1839
+ | 2 | 2.0 | 0.0 |
1840
+ | 3 | 2.5 | 0.2375 |
1841
+ | 4 | 3.0 | 0.45 |
1842
+ | 5 | 3.5 | 0.6375 |
1843
+ | 6 | 4.0 | 0.8 |
1844
+ | 7 | 4.5 | 0.75 |
1845
+ """
1846
+
1847
+ CONTROLPARAMETERS = (
1848
+ sw1d_control.Gradient2PumpingRate,
1849
+ sw1d_control.TargetWaterLevel1,
1850
+ sw1d_control.TargetWaterLevel2,
1851
+ )
1852
+ REQUIREDSEQUENCES = (
1853
+ sw1d_factors.WaterLevelUpstream,
1854
+ sw1d_factors.WaterLevelDownstream,
1855
+ )
1856
+ UPDATEDSEQUENCES = (sw1d_states.Discharge,)
1857
+
1858
+ @staticmethod
1859
+ def __call__(model: modeltools.Model) -> None:
1860
+ con = model.parameters.control.fastaccess
1861
+ fac = model.sequences.factors.fastaccess
1862
+ sta = model.sequences.states.fastaccess
1863
+
1864
+ hu: float = fac.waterlevelupstream
1865
+ hd: float = fac.waterleveldownstream
1866
+ t1: float = con.targetwaterlevel1
1867
+ t2: float = con.targetwaterlevel2
1868
+
1869
+ if hu < t1:
1870
+ sta.discharge = 0.0
1871
+ else:
1872
+ con.gradient2pumpingrate.inputs[0] = hu - hd
1873
+ con.gradient2pumpingrate.calculate_values()
1874
+ sta.discharge = max(con.gradient2pumpingrate.outputs[0], 0.0)
1875
+ if hu < t2:
1876
+ sta.discharge *= (hu - t1) / (t2 - t1)
1877
+
1878
+
1879
+ class Update_Discharge_V1(modeltools.Method):
1880
+ r"""Reduce the already calculated discharge due to limited water availability in
1881
+ one of the adjacent channel segments.
1882
+
1883
+ Basic equations:
1884
+ .. math::
1885
+ Q_{new} = \begin{cases}
1886
+ max(Q_{old}, \ 1000 \cdot max(V_u, \ 0) / \Delta &|\ Q_{old} > 0 \\
1887
+ min(Q_{old}, \ -1000 \cdot max(V_d, \ 0) / \Delta &|\ Q_{old} < 0
1888
+ \end{cases} \\
1889
+ \\ \\
1890
+ Q = Discharge \\
1891
+ V_u = WaterVolumeUpstream \\
1892
+ V_d = WaterVolumeDownstream \\
1893
+ \Delta = TimeStep
1894
+
1895
+ Examples:
1896
+
1897
+ >>> from hydpy.models.sw1d import *
1898
+ >>> parameterstep()
1899
+ >>> factors.timestep = 100.0
1900
+ >>> factors.watervolumeupstream = 0.1
1901
+ >>> factors.watervolumedownstream = 0.2
1902
+
1903
+ |Update_Discharge_V1| must consider the upstream segment's water volume for
1904
+ positive discharge values:
1905
+
1906
+ >>> states.discharge = 1.0
1907
+ >>> model.update_discharge_v1()
1908
+ >>> states.discharge
1909
+ discharge(1.0)
1910
+ >>> states.discharge = 2.0
1911
+ >>> model.update_discharge_v1()
1912
+ >>> states.discharge
1913
+ discharge(1.0)
1914
+
1915
+ Instead, it must consider the downstream segment's water volume for negative
1916
+ discharge values:
1917
+
1918
+ >>> states.discharge = -2.0
1919
+ >>> model.update_discharge_v1()
1920
+ >>> states.discharge
1921
+ discharge(-2.0)
1922
+ >>> states.discharge = -3.0
1923
+ >>> model.update_discharge_v1()
1924
+ >>> states.discharge
1925
+ discharge(-2.0)
1926
+ """
1927
+
1928
+ REQUIREDSEQUENCES = (
1929
+ sw1d_factors.TimeStep,
1930
+ sw1d_factors.WaterVolumeUpstream,
1931
+ sw1d_factors.WaterVolumeDownstream,
1932
+ )
1933
+ UPDATEDSEQUENCES = (sw1d_states.Discharge,)
1934
+
1935
+ @staticmethod
1936
+ def __call__(model: modeltools.Model) -> None:
1937
+ fac = model.sequences.factors.fastaccess
1938
+ sta = model.sequences.states.fastaccess
1939
+ if sta.discharge > 0.0:
1940
+ q_max: float = 1000.0 * max(fac.watervolumeupstream, 0.0) / fac.timestep
1941
+ sta.discharge = min(sta.discharge, q_max)
1942
+ elif sta.discharge < 0.0:
1943
+ q_min: float = -1000.0 * max(fac.watervolumedownstream, 0.0) / fac.timestep
1944
+ sta.discharge = max(sta.discharge, q_min)
1945
+
1946
+
1947
+ class Update_Discharge_V2(modeltools.Method):
1948
+ r"""Sluice-like discharge reduction with separate control for low and high flow
1949
+ protection.
1950
+
1951
+ Basic equations:
1952
+ .. math::
1953
+ Q_{new} = Q_{new} \cdot \begin{cases}
1954
+ free &|\ h_u \leq h_d \\
1955
+ free + sluice &|\ h_d < h_u \\
1956
+ \end{cases} \\
1957
+ \\ \\
1958
+ closed = \begin{cases}
1959
+ 1 &|\ h_u \leq t_{bl} \\
1960
+ 1 - \frac{h_u - t_{bl}}{t_{ul} - t_{bl}} &|\ t_{bl} < h_u < t_{ul} \\
1961
+ 0 &|\ t_{ul} \leq h_u
1962
+ \end{cases} \\
1963
+ \\
1964
+ sluice = \begin{cases}
1965
+ 0 &|\ h_u \leq t_{bh} \\
1966
+ \frac{h_u - t_{bh}}{t_{uh} - t_{bh}} &|\ t_{bh} < h_u < t_{uh} \\
1967
+ 1 &|\ t_{uh} \leq h_u
1968
+ \end{cases} \\
1969
+ \\
1970
+ free = 1 - closed - sluice \\
1971
+ \\
1972
+ Q = Discharge \\
1973
+ h_u = WaterLevelUpstream \\
1974
+ h_d = WaterLevelDownstream \\
1975
+ t_{bl} = BottomLowWaterThreshold \\
1976
+ t_{ul} = UpperLowWaterThreshold \\
1977
+ t_{bh} = BottomHighWaterThreshold \\
1978
+ t_{uh} = UpperHighWaterThreshold
1979
+
1980
+ Examples:
1981
+
1982
+ All involved control parameters are subclasses of |SeasonalParameter|, which
1983
+ allows the simulation of seasonal sluice control schemes. To show how this
1984
+ works, we first define a simulation period of four days:
1985
+
1986
+ >>> from hydpy import pub
1987
+ >>> pub.timegrids = "2000-01-01", "2000-01-05", "1d"
1988
+
1989
+ We prepare a model and define different control schemes for four consecutive
1990
+ days:
1991
+
1992
+ >>> from hydpy.models.sw1d import *
1993
+ >>> parameterstep()
1994
+ >>> bottomlowwaterthreshold(_1_1_12=5.0, _1_2_12=2.0, _1_3_12=2.0, _1_4_12=2.0)
1995
+ >>> upperlowwaterthreshold(_1_1_12=5.0, _1_2_12=8.0, _1_3_12=5.0, _1_4_12=6.0)
1996
+ >>> bottomhighwaterthreshold(_1_1_12=5.0, _1_2_12=2.0, _1_3_12=5.0, _1_4_12=4.0)
1997
+ >>> upperhighwaterthreshold(_1_1_12=5.0, _1_2_12=8.0, _1_3_12=8.0, _1_4_12=8.0)
1998
+ >>> derived.toy.update()
1999
+
2000
+ We prepare a |UnitTest| object to demonstrate the dependency of
2001
+ |Update_Discharge_V2| on the downstream water level:
2002
+
2003
+ >>> from hydpy import UnitTest
2004
+ >>> test = UnitTest(model, model.update_discharge_v2, last_example=9,
2005
+ ... parseqs=(factors.waterlevelupstream, states.discharge))
2006
+ >>> test.nexts.waterlevelupstream = 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0
2007
+
2008
+ We will discuss each day's control scheme for a normal flow situation with a
2009
+ relatively low downstream water level and a reversed flow situation with a
2010
+ relatively high downstream water level.
2011
+
2012
+ For April 1, all threshold parameters have the same value of 5 m. So, gates
2013
+ are generally closed below an upstream water level of 5 m to prevent
2014
+ the source catchment from running dry during low flow periods ("closed gate")
2015
+ and only allow normal flow above 5 m to maximise drainage during high flow
2016
+ periods ("sluice mode"):
2017
+
2018
+ >>> model.idx_sim = pub.timegrids.init["2000-01-01"]
2019
+ >>> factors.waterleveldownstream = 0.0
2020
+ >>> test.inits.discharge = 1.0
2021
+ >>> test()
2022
+ | ex. | waterlevelupstream | discharge |
2023
+ ----------------------------------------
2024
+ | 1 | 1.0 | 0.0 |
2025
+ | 2 | 2.0 | 0.0 |
2026
+ | 3 | 3.0 | 0.0 |
2027
+ | 4 | 4.0 | 0.0 |
2028
+ | 5 | 5.0 | 1.0 |
2029
+ | 6 | 6.0 | 1.0 |
2030
+ | 7 | 7.0 | 1.0 |
2031
+ | 8 | 8.0 | 1.0 |
2032
+ | 9 | 9.0 | 1.0 |
2033
+
2034
+ >>> factors.waterleveldownstream = 10.0
2035
+ >>> test.inits.discharge = -1.0
2036
+ >>> test()
2037
+ | ex. | waterlevelupstream | discharge |
2038
+ ----------------------------------------
2039
+ | 1 | 1.0 | 0.0 |
2040
+ | 2 | 2.0 | 0.0 |
2041
+ | 3 | 3.0 | 0.0 |
2042
+ | 4 | 4.0 | 0.0 |
2043
+ | 5 | 5.0 | 0.0 |
2044
+ | 6 | 6.0 | 0.0 |
2045
+ | 7 | 7.0 | 0.0 |
2046
+ | 8 | 8.0 | 0.0 |
2047
+ | 9 | 9.0 | 0.0 |
2048
+
2049
+ In the following examples, he transitions between the low and high water
2050
+ control schemes are not sharp but gradual, which is often more realistic and
2051
+ numerically favourable. For April 2, the values of |BottomLowWaterThreshold|
2052
+ and |BottomHighWaterThreshold| and the values of |UpperLowWaterThreshold| and
2053
+ |UpperHighWaterThreshold| are equal. Hence, we see a linear-interpolation-like
2054
+ transition from the "closed gate" to the "sluice mode" control schemes:
2055
+
2056
+ >>> model.idx_sim = pub.timegrids.init["2000-01-02"]
2057
+ >>> factors.waterleveldownstream = 0.0
2058
+ >>> test.inits.discharge = 1.0
2059
+ >>> test()
2060
+ | ex. | waterlevelupstream | discharge |
2061
+ ----------------------------------------
2062
+ | 1 | 1.0 | 0.0 |
2063
+ | 2 | 2.0 | 0.0 |
2064
+ | 3 | 3.0 | 0.166667 |
2065
+ | 4 | 4.0 | 0.333333 |
2066
+ | 5 | 5.0 | 0.5 |
2067
+ | 6 | 6.0 | 0.666667 |
2068
+ | 7 | 7.0 | 0.833333 |
2069
+ | 8 | 8.0 | 1.0 |
2070
+ | 9 | 9.0 | 1.0 |
2071
+
2072
+ >>> factors.waterleveldownstream = 10.0
2073
+ >>> test.inits.discharge = -1.0
2074
+ >>> test()
2075
+ | ex. | waterlevelupstream | discharge |
2076
+ ----------------------------------------
2077
+ | 1 | 1.0 | 0.0 |
2078
+ | 2 | 2.0 | 0.0 |
2079
+ | 3 | 3.0 | 0.0 |
2080
+ | 4 | 4.0 | 0.0 |
2081
+ | 5 | 5.0 | 0.0 |
2082
+ | 6 | 6.0 | 0.0 |
2083
+ | 7 | 7.0 | 0.0 |
2084
+ | 8 | 8.0 | 0.0 |
2085
+ | 9 | 9.0 | 0.0 |
2086
+
2087
+ For April 3, the values of |UpperLowWaterThreshold| and
2088
+ |BottomHighWaterThreshold| are equal. So, at this point, neither the "closed
2089
+ gate" nor the "sluice mode" control schemes apply, and the water can flow
2090
+ freely in both directions ("free discharge"):
2091
+
2092
+ >>> model.idx_sim = pub.timegrids.init["2000-01-03"]
2093
+ >>> factors.waterleveldownstream = 0.0
2094
+ >>> test.inits.discharge = 1.0
2095
+ >>> test()
2096
+ | ex. | waterlevelupstream | discharge |
2097
+ ----------------------------------------
2098
+ | 1 | 1.0 | 0.0 |
2099
+ | 2 | 2.0 | 0.0 |
2100
+ | 3 | 3.0 | 0.333333 |
2101
+ | 4 | 4.0 | 0.666667 |
2102
+ | 5 | 5.0 | 1.0 |
2103
+ | 6 | 6.0 | 1.0 |
2104
+ | 7 | 7.0 | 1.0 |
2105
+ | 8 | 8.0 | 1.0 |
2106
+ | 9 | 9.0 | 1.0 |
2107
+
2108
+ >>> factors.waterleveldownstream = 10.0
2109
+ >>> test.inits.discharge = -1.0
2110
+ >>> test()
2111
+ | ex. | waterlevelupstream | discharge |
2112
+ ----------------------------------------
2113
+ | 1 | 1.0 | 0.0 |
2114
+ | 2 | 2.0 | 0.0 |
2115
+ | 3 | 3.0 | -0.333333 |
2116
+ | 4 | 4.0 | -0.666667 |
2117
+ | 5 | 5.0 | -1.0 |
2118
+ | 6 | 6.0 | -0.666667 |
2119
+ | 7 | 7.0 | -0.333333 |
2120
+ | 8 | 8.0 | 0.0 |
2121
+ | 9 | 9.0 | 0.0 |
2122
+
2123
+
2124
+ For April 4, the "closed gate" and "sluice mode" parameter ranges are partly
2125
+ overlapping, so reversed flow can occur but only with reduced intensity:
2126
+
2127
+ >>> model.idx_sim = pub.timegrids.init["2000-01-04"]
2128
+ >>> factors.waterleveldownstream = 0.0
2129
+ >>> test.inits.discharge = 1.0
2130
+ >>> test()
2131
+ | ex. | waterlevelupstream | discharge |
2132
+ ----------------------------------------
2133
+ | 1 | 1.0 | 0.0 |
2134
+ | 2 | 2.0 | 0.0 |
2135
+ | 3 | 3.0 | 0.25 |
2136
+ | 4 | 4.0 | 0.5 |
2137
+ | 5 | 5.0 | 0.75 |
2138
+ | 6 | 6.0 | 1.0 |
2139
+ | 7 | 7.0 | 1.0 |
2140
+ | 8 | 8.0 | 1.0 |
2141
+ | 9 | 9.0 | 1.0 |
2142
+
2143
+ >>> factors.waterleveldownstream = 10.0
2144
+ >>> test.inits.discharge = -1.0
2145
+ >>> test()
2146
+ | ex. | waterlevelupstream | discharge |
2147
+ ----------------------------------------
2148
+ | 1 | 1.0 | 0.0 |
2149
+ | 2 | 2.0 | 0.0 |
2150
+ | 3 | 3.0 | -0.25 |
2151
+ | 4 | 4.0 | -0.5 |
2152
+ | 5 | 5.0 | -0.5 |
2153
+ | 6 | 6.0 | -0.5 |
2154
+ | 7 | 7.0 | -0.25 |
2155
+ | 8 | 8.0 | 0.0 |
2156
+ | 9 | 9.0 | 0.0 |
2157
+
2158
+ .. testsetup::
2159
+
2160
+ >>> del pub.timegrids
2161
+ """
2162
+
2163
+ CONTROLPARAMETERS = (
2164
+ sw1d_control.BottomLowWaterThreshold,
2165
+ sw1d_control.UpperLowWaterThreshold,
2166
+ sw1d_control.BottomHighWaterThreshold,
2167
+ sw1d_control.UpperHighWaterThreshold,
2168
+ )
2169
+ DERIVEDPARAMETERS = (sw1d_derived.TOY,)
2170
+ REQUIREDSEQUENCES = (
2171
+ sw1d_factors.WaterLevelUpstream,
2172
+ sw1d_factors.WaterLevelDownstream,
2173
+ )
2174
+ UPDATEDSEQUENCES = (sw1d_states.Discharge,)
2175
+
2176
+ @staticmethod
2177
+ def __call__(model: modeltools.Model) -> None:
2178
+ con = model.parameters.control.fastaccess
2179
+ der = model.parameters.derived.fastaccess
2180
+ fac = model.sequences.factors.fastaccess
2181
+ sta = model.sequences.states.fastaccess
2182
+
2183
+ hu: float = fac.waterlevelupstream
2184
+ hd: float = fac.waterleveldownstream
2185
+ toy = der.toy[model.idx_sim]
2186
+ lt1: float = con.bottomlowwaterthreshold[toy]
2187
+ lt2: float = con.upperlowwaterthreshold[toy]
2188
+ ht1: float = con.bottomhighwaterthreshold[toy]
2189
+ ht2: float = con.upperhighwaterthreshold[toy]
2190
+
2191
+ # Is the sluice generally closed? (low water protection)
2192
+ if hu < lt1:
2193
+ state_closed: float = 1.0
2194
+ elif hu < lt2:
2195
+ state_closed = 1.0 - (hu - lt1) / (lt2 - lt1)
2196
+ else:
2197
+ state_closed = 0.0
2198
+ # Is the sluice in real sluice mode? (high water protection)
2199
+ if hu < ht1:
2200
+ state_sluice: float = 0.0
2201
+ elif hu < ht2:
2202
+ state_sluice = (hu - ht1) / (ht2 - ht1)
2203
+ else:
2204
+ state_sluice = 1.0
2205
+ # Is the sluice generally open? (no protection measures necessary)
2206
+ state_free: float = 1.0 - state_closed - state_sluice
2207
+
2208
+ sta.discharge *= state_free + (state_sluice if hu > hd else 0.0)
2209
+
2210
+
2211
+ class Reset_DischargeVolume_V1(modeltools.Method):
2212
+ """Reset the discharge volume to zero (at the beginning of an external simulation
2213
+ step).
2214
+
2215
+ Example:
2216
+
2217
+ >>> from hydpy.models.sw1d import *
2218
+ >>> parameterstep()
2219
+ >>> fluxes.dischargevolume = 1.0
2220
+ >>> model.reset_dischargevolume_v1()
2221
+ >>> fluxes.dischargevolume
2222
+ dischargevolume(0.0)
2223
+ """
2224
+
2225
+ RESULTSEQUENCES = (sw1d_fluxes.DischargeVolume,)
2226
+
2227
+ @staticmethod
2228
+ def __call__(model: modeltools.Model) -> None:
2229
+ flu = model.sequences.fluxes.fastaccess
2230
+ flu.dischargevolume = 0.0
2231
+
2232
+
2233
+ class Update_DischargeVolume_V1(modeltools.Method):
2234
+ r"""Update the total discharge volume of the current external simulation step.
2235
+
2236
+ Basic equation:
2237
+ :math:`DischargeVolume_{new} = DischargeVolume_{old} + TimeStep \cdot Discharge`
2238
+
2239
+ Example:
2240
+
2241
+ >>> from hydpy.models.sw1d import *
2242
+ >>> parameterstep()
2243
+ >>> fluxes.dischargevolume = 6.0
2244
+ >>> factors.timestep = 60.0
2245
+ >>> states.discharge = 0.2
2246
+ >>> model.update_dischargevolume_v1()
2247
+ >>> fluxes.dischargevolume
2248
+ dischargevolume(18.0)
2249
+ """
2250
+
2251
+ REQUIREDSEQUENCES = (sw1d_factors.TimeStep, sw1d_states.Discharge)
2252
+ UPDATEDSEQUENCES = (sw1d_fluxes.DischargeVolume,)
2253
+
2254
+ @staticmethod
2255
+ def __call__(model: modeltools.Model) -> None:
2256
+ fac = model.sequences.factors.fastaccess
2257
+ flu = model.sequences.fluxes.fastaccess
2258
+ sta = model.sequences.states.fastaccess
2259
+ flu.dischargevolume += fac.timestep * sta.discharge
2260
+
2261
+
2262
+ class Calc_DischargeVolume_V1(modeltools.Method):
2263
+ r"""Calculate the total discharge volume of a complete external simulation step at
2264
+ once.
2265
+
2266
+ Basic equation:
2267
+ :math:`DischargeVolume = Seconds \cdot Inflow`
2268
+
2269
+ Example:
2270
+
2271
+ >>> from hydpy.models.sw1d import *
2272
+ >>> parameterstep()
2273
+ >>> derived.seconds(60.0)
2274
+ >>> fluxes.inflow = 2.0
2275
+ >>> model.calc_dischargevolume_v1()
2276
+ >>> fluxes.dischargevolume
2277
+ dischargevolume(120.0)
2278
+ """
2279
+
2280
+ DERIVEDPARAMETERS = (sw1d_derived.Seconds,)
2281
+ REQUIREDSEQUENCES = (sw1d_fluxes.Inflow,)
2282
+ UPDATEDSEQUENCES = (sw1d_fluxes.DischargeVolume,)
2283
+
2284
+ @staticmethod
2285
+ def __call__(model: modeltools.Model) -> None:
2286
+ der = model.parameters.derived.fastaccess
2287
+ flu = model.sequences.fluxes.fastaccess
2288
+ flu.dischargevolume = der.seconds * flu.inflow
2289
+
2290
+
2291
+ class Calc_DischargeVolume_V2(modeltools.Method):
2292
+ r"""Calculate the total discharge volume of a complete external simulation step at
2293
+ once.
2294
+
2295
+ Basic equation:
2296
+ :math:`DischargeVolume = Seconds \cdot Outflow`
2297
+
2298
+ Example:
2299
+
2300
+ >>> from hydpy.models.sw1d import *
2301
+ >>> parameterstep()
2302
+ >>> derived.seconds(60.0)
2303
+ >>> fluxes.outflow = 2.0
2304
+ >>> model.calc_dischargevolume_v2()
2305
+ >>> fluxes.dischargevolume
2306
+ dischargevolume(120.0)
2307
+ """
2308
+
2309
+ DERIVEDPARAMETERS = (sw1d_derived.Seconds,)
2310
+ REQUIREDSEQUENCES = (sw1d_fluxes.Outflow,)
2311
+ UPDATEDSEQUENCES = (sw1d_fluxes.DischargeVolume,)
2312
+
2313
+ @staticmethod
2314
+ def __call__(model: modeltools.Model) -> None:
2315
+ der = model.parameters.derived.fastaccess
2316
+ flu = model.sequences.fluxes.fastaccess
2317
+ flu.dischargevolume = der.seconds * flu.outflow
2318
+
2319
+
2320
+ class Calc_Discharges_V1(modeltools.Method):
2321
+ """Let a network model order all routing submodels following the |RoutingModel_V1|,
2322
+ |RoutingModel_V2|, or |RoutingModel_V3| interface to determine their individual
2323
+ discharge values.
2324
+
2325
+ Example:
2326
+
2327
+ >>> from hydpy.models.sw1d_channel import *
2328
+ >>> parameterstep()
2329
+ >>> nmbsegments(2)
2330
+ >>> with model.add_routingmodel_v2("sw1d_lias", position=1, update=False) as r:
2331
+ ... diffusionfactor(0.2)
2332
+ ... stricklercoefficient(50.0)
2333
+ ... derived.lengthmean(2.0)
2334
+ ... factors.timestep = 100.0
2335
+ ... factors.wettedarea = 6.0
2336
+ ... factors.wettedperimeter = 8.0
2337
+ ... factors.waterlevelupstream = 5.0
2338
+ ... factors.waterleveldownstream = 3.0
2339
+ ... states.discharge = 7.831208
2340
+ ... fluxes.dischargeupstream = 7.831208
2341
+ ... fluxes.dischargedownstream = 7.831208
2342
+ >>> model.calc_discharges_v1()
2343
+ >>> r.sequences.states.discharge
2344
+ discharge(7.831208)
2345
+ """
2346
+
2347
+ SUBMODELINTERFACES = (
2348
+ routinginterfaces.RoutingModel_V1,
2349
+ routinginterfaces.RoutingModel_V2,
2350
+ routinginterfaces.RoutingModel_V3,
2351
+ )
2352
+
2353
+ @staticmethod
2354
+ def __call__(model: modeltools.Model) -> None:
2355
+ for i in range(model.routingmodels.number):
2356
+ if model.routingmodels.typeids[i] in (1, 2, 3):
2357
+ cast(
2358
+ RoutingModels_V1_V2_V3, model.routingmodels.submodels[i]
2359
+ ).determine_discharge()
2360
+
2361
+
2362
+ class Calc_Discharges_V2(modeltools.Method):
2363
+ """Query the discharge volume of the complete external simulation step from all
2364
+ submodels following the |RoutingModel_V1|, |RoutingModel_V2|, or |RoutingModel_V3|
2365
+ interface and calculate the corresponding average discharges.
2366
+
2367
+ Basic equation:
2368
+ :math:`Discharges_i = DischargeVolume / Seconds`
2369
+
2370
+ Examples:
2371
+
2372
+ >>> from hydpy.models.sw1d_channel import *
2373
+ >>> parameterstep()
2374
+ >>> nmbsegments(2)
2375
+ >>> derived.seconds(60.0)
2376
+ >>> with model.add_routingmodel_v2("sw1d_lias", position=1, update=False):
2377
+ ... fluxes.dischargevolume = 120.0
2378
+ >>> model.calc_discharges_v2()
2379
+ >>> fluxes.discharges
2380
+ discharges(0.0, 2.0, 0.0)
2381
+ """
2382
+
2383
+ SUBMODELINTERFACES = (
2384
+ routinginterfaces.RoutingModel_V1,
2385
+ routinginterfaces.RoutingModel_V2,
2386
+ routinginterfaces.RoutingModel_V3,
2387
+ )
2388
+ DERIVEDPARAMETERS = (sw1d_derived.Seconds,)
2389
+ RESULTSEQUENCES = (sw1d_fluxes.Discharges,)
2390
+
2391
+ @staticmethod
2392
+ def __call__(model: modeltools.Model) -> None:
2393
+ der = model.parameters.derived.fastaccess
2394
+ flu = model.sequences.fluxes.fastaccess
2395
+
2396
+ for i in range(model.routingmodels.number):
2397
+ if model.routingmodels.typeids[i] in (1, 2, 3):
2398
+ flu.discharges[i] = (
2399
+ cast(
2400
+ RoutingModels_V1_V2_V3, model.routingmodels.submodels[i]
2401
+ ).get_dischargevolume()
2402
+ / der.seconds
2403
+ )
2404
+ else:
2405
+ flu.discharges[i] = 0.0
2406
+
2407
+
2408
+ class Calc_NetInflow_V1(modeltools.Method):
2409
+ """Calculate the net flow into a channel segment.
2410
+
2411
+ Examples:
2412
+
2413
+ Without adjacent routing models, net inflow equals lateral inflow:
2414
+
2415
+ >>> from hydpy import Element, Node, prepare_model
2416
+ >>> c = prepare_model("sw1d_channel")
2417
+ >>> c.parameters.control.nmbsegments(1)
2418
+ >>> with c.add_storagemodel_v1("sw1d_storage", position=0, update=False) as s:
2419
+ ... factors.timestep = 100.0
2420
+ ... fluxes.lateralflow = 1.0
2421
+ >>> s.calc_netinflow_v1()
2422
+ >>> s.sequences.fluxes.netinflow
2423
+ netinflow(0.1)
2424
+
2425
+ With adjacent routing models, |Calc_NetInflow_V1| adds the discharge from the
2426
+ upper one and subtracts the discharge from the lower one:
2427
+
2428
+ >>> n01, n12 = Node("n01", variable="LongQ"), Node("n12", variable="LongQ")
2429
+ >>> e1 = Element("e1", inlets=n01, outlets=n12)
2430
+ >>> e1.model = c
2431
+ >>> e0a, e0b = Element("e0a", outlets=n01), Element("e0b", outlets=n01)
2432
+ >>> e2a, e2b = Element("e2a", inlets=n12), Element("e2b", inlets=n12)
2433
+ >>> for element, position, discharge in ((e0a, 1, 1.0), (e0b, 1, 2.0),
2434
+ ... (e2a, 0, 2.0), (e2b, 0, 3.0)):
2435
+ ... c = prepare_model("sw1d_channel")
2436
+ ... element.model = c
2437
+ ... c.parameters.control.nmbsegments(1)
2438
+ ... with c.add_routingmodel_v2(
2439
+ ... "sw1d_lias", position=position, update=False):
2440
+ ... states.discharge = discharge
2441
+ ... with c.add_storagemodel_v1("sw1d_storage", position=0, update=False):
2442
+ ... pass
2443
+ >>> network = c.couple_models(
2444
+ ... nodes=(n01, n12), elements=(e0a, e0b, e1, e2a, e2b))
2445
+ >>> s.calc_netinflow_v1()
2446
+ >>> s.sequences.fluxes.netinflow
2447
+ netinflow(-0.1)
2448
+
2449
+ .. testsetup::
2450
+
2451
+ >>> Node.clear_all()
2452
+ >>> Element.clear_all()
2453
+ """
2454
+
2455
+ SUBMODELINTERFACES = (
2456
+ routinginterfaces.RoutingModel_V1,
2457
+ routinginterfaces.RoutingModel_V2,
2458
+ routinginterfaces.StorageModel_V1,
2459
+ )
2460
+ REQUIREDSEQUENCES = (sw1d_factors.TimeStep, sw1d_fluxes.LateralFlow)
2461
+ RESULTSEQUENCES = (sw1d_fluxes.NetInflow,)
2462
+
2463
+ @staticmethod
2464
+ def __call__(model: modeltools.Model) -> None:
2465
+ fac = model.sequences.factors.fastaccess
2466
+ flu = model.sequences.fluxes.fastaccess
2467
+ flu.netinflow = flu.lateralflow
2468
+ for i in range(model.routingmodelsupstream.number):
2469
+ if model.routingmodelsupstream.typeids[i] in (1, 2):
2470
+ flu.netinflow += cast(
2471
+ RoutingModels_V1_V2, model.routingmodelsupstream.submodels[i]
2472
+ ).get_discharge()
2473
+ for i in range(model.routingmodelsdownstream.number):
2474
+ if model.routingmodelsdownstream.typeids[i] in (2, 3):
2475
+ flu.netinflow -= cast(
2476
+ RoutingModels_V2_V3, model.routingmodelsdownstream.submodels[i]
2477
+ ).get_discharge()
2478
+ flu.netinflow *= fac.timestep / 1e3
2479
+
2480
+
2481
+ class Update_WaterVolume_V1(modeltools.Method):
2482
+ """Update the current water content of a channel segment.
2483
+
2484
+ Example:
2485
+
2486
+ >>> from hydpy.models.sw1d import *
2487
+ >>> parameterstep()
2488
+ >>> states.watervolume = 2.0
2489
+ >>> fluxes.netinflow = 1.0
2490
+ >>> model.update_watervolume_v1()
2491
+ >>> states.watervolume
2492
+ watervolume(3.0)
2493
+ """
2494
+
2495
+ REQUIREDSEQUENCES = (sw1d_fluxes.NetInflow,)
2496
+ UPDATEDSEQUENCES = (sw1d_states.WaterVolume,)
2497
+
2498
+ @staticmethod
2499
+ def __call__(model: modeltools.Model) -> None:
2500
+ flu = model.sequences.fluxes.fastaccess
2501
+ sta = model.sequences.states.fastaccess
2502
+ sta.watervolume += flu.netinflow
2503
+
2504
+
2505
+ class Update_Storages_V1(modeltools.Method):
2506
+ """Let a network model order all storage submodels to update their storage contents
2507
+ and their dependent factors.
2508
+
2509
+ Example:
2510
+
2511
+ >>> from hydpy.models.sw1d_channel import *
2512
+ >>> parameterstep()
2513
+ >>> nmbsegments(1)
2514
+ >>> with model.add_routingmodel_v2("sw1d_lias", position=0, update=False):
2515
+ ... states.discharge = 50.0
2516
+ >>> with model.add_storagemodel_v1("sw1d_storage", position=0, update=False):
2517
+ ... length(2.0)
2518
+ ... states.watervolume = 2.0
2519
+ ... factors.timestep = 100.0
2520
+ ... fluxes.lateralflow = 1.0
2521
+ >>> with model.add_routingmodel_v2("sw1d_lias", position=1, update=False):
2522
+ ... states.discharge = 60.0
2523
+ >>> model.update_storages()
2524
+ >>> model.storagemodels[0].sequences.states.watervolume
2525
+ watervolume(1.1)
2526
+ """
2527
+
2528
+ SUBMODELINTERFACES = (routinginterfaces.StorageModel_V1,)
2529
+
2530
+ @staticmethod
2531
+ def __call__(model: modeltools.Model) -> None:
2532
+ for i in range(model.storagemodels.number):
2533
+ if model.storagemodels.typeids[i] == 1:
2534
+ cast(
2535
+ routinginterfaces.StorageModel_V1, model.storagemodels.submodels[i]
2536
+ ).update_storage()
2537
+
2538
+
2539
+ class Query_WaterLevels_V1(modeltools.Method):
2540
+ """Query the water levels from all submodels following the |StorageModel_V1|
2541
+ interface.
2542
+
2543
+ Example:
2544
+
2545
+ >>> from hydpy.models.sw1d_channel import *
2546
+ >>> parameterstep()
2547
+ >>> nmbsegments(2)
2548
+ >>> with model.add_storagemodel_v1("sw1d_storage", position=0, update=False):
2549
+ ... factors.waterlevel = 1.0
2550
+ >>> with model.add_storagemodel_v1("sw1d_storage", position=1, update=False):
2551
+ ... factors.waterlevel = -1.0
2552
+ >>> model.query_waterlevels_v1()
2553
+ >>> factors.waterlevels
2554
+ waterlevels(1.0, -1.0)
2555
+ """
2556
+
2557
+ SUBMODELINTERFACES = (routinginterfaces.StorageModel_V1,)
2558
+ RESULTSEQUENCES = (sw1d_factors.WaterLevels,)
2559
+
2560
+ @staticmethod
2561
+ def __call__(model: modeltools.Model) -> None:
2562
+ fac = model.sequences.factors.fastaccess
2563
+
2564
+ for i in range(model.storagemodels.number):
2565
+ if model.storagemodels.typeids[i] == 1:
2566
+ fac.waterlevels[i] = cast(
2567
+ routinginterfaces.StorageModel_V1, model.storagemodels.submodels[i]
2568
+ ).get_waterlevel()
2569
+
2570
+
2571
+ # interface methods
2572
+
2573
+
2574
+ class Perform_Preprocessing_V1(modeltools.AutoMethod):
2575
+ """Routing model interface method for preprocessing data that is invariant within
2576
+ each external simulation step."""
2577
+
2578
+ SUBMETHODS = (Pick_Inflow_V1,)
2579
+ REQUIREDSEQUENCES = (sw1d_inlets.LongQ,)
2580
+ RESULTSEQUENCES = (sw1d_fluxes.Inflow,)
2581
+
2582
+
2583
+ class Perform_Preprocessing_V2(modeltools.AutoMethod):
2584
+ """Routing model interface method for preprocessing data that is invariant within
2585
+ each external simulation step."""
2586
+
2587
+ SUBMETHODS = (Reset_DischargeVolume_V1,)
2588
+ RESULTSEQUENCES = (sw1d_fluxes.DischargeVolume,)
2589
+
2590
+
2591
+ class Perform_Preprocessing_V3(modeltools.AutoMethod):
2592
+ """Storage model interface method for preprocessing data that is invariant within
2593
+ each external simulation step."""
2594
+
2595
+ SUBMETHODS = (Pick_LateralFlow_V1, Calc_WaterDepth_WaterLevel_V1)
2596
+ CONTROLPARAMETERS = (sw1d_control.Length,)
2597
+ REQUIREDSEQUENCES = (sw1d_inlets.LatQ, sw1d_states.WaterVolume)
2598
+ RESULTSEQUENCES = (
2599
+ sw1d_factors.WaterDepth,
2600
+ sw1d_factors.WaterLevel,
2601
+ sw1d_fluxes.LateralFlow,
2602
+ )
2603
+
2604
+
2605
+ class Perform_Preprocessing_V4(modeltools.AutoMethod):
2606
+ """Routing model interface method for preprocessing data that is invariant within
2607
+ each external simulation step."""
2608
+
2609
+ SUBMETHODS = (Pick_Outflow_V1,)
2610
+ REQUIREDSEQUENCES = (sw1d_outlets.LongQ,)
2611
+ RESULTSEQUENCES = (sw1d_fluxes.Outflow,)
2612
+
2613
+
2614
+ class Perform_Preprocessing_V5(modeltools.AutoMethod):
2615
+ """Routing model interface method for preprocessing data that is invariant within
2616
+ each external simulation step."""
2617
+
2618
+ SUBMETHODS = (Pick_WaterLevelDownstream_V1, Reset_DischargeVolume_V1)
2619
+ REQUIREDSEQUENCES = (sw1d_receivers.WaterLevel,)
2620
+ RESULTSEQUENCES = (sw1d_factors.WaterLevelDownstream, sw1d_fluxes.DischargeVolume)
2621
+
2622
+
2623
+ class Perform_Postprocessing_V1(modeltools.AutoMethod):
2624
+ """Routing model interface method for executing all tasks necessary at the end of
2625
+ each external simulation step."""
2626
+
2627
+ SUBMETHODS = (Calc_DischargeVolume_V1,)
2628
+ DERIVEDPARAMETERS = (sw1d_derived.Seconds,)
2629
+ REQUIREDSEQUENCES = (sw1d_fluxes.Inflow,)
2630
+ UPDATEDSEQUENCES = (sw1d_fluxes.DischargeVolume,)
2631
+
2632
+
2633
+ class Perform_Postprocessing_V2(modeltools.AutoMethod):
2634
+ """Routing model interface method for executing all tasks necessary at the end of
2635
+ each external simulation step."""
2636
+
2637
+ SUBMETHODS = (Pass_Discharge_V1,)
2638
+ DERIVEDPARAMETERS = (sw1d_derived.Seconds,)
2639
+ REQUIREDSEQUENCES = (sw1d_fluxes.DischargeVolume,)
2640
+ RESULTSEQUENCES = (sw1d_inlets.LongQ, sw1d_outlets.LongQ)
2641
+
2642
+
2643
+ class Perform_Postprocessing_V3(modeltools.AutoMethod):
2644
+ """Storage model interface method for executing all tasks necessary at the end of
2645
+ each external simulation step."""
2646
+
2647
+ SUBMETHODS = (Pass_WaterLevel_V1,)
2648
+ REQUIREDSEQUENCES = (sw1d_factors.WaterLevel,)
2649
+ RESULTSEQUENCES = (sw1d_senders.WaterLevel,)
2650
+
2651
+
2652
+ class Perform_Postprocessing_V4(modeltools.AutoMethod):
2653
+ """Routing model interface method for executing all tasks necessary at the end of
2654
+ each external simulation step."""
2655
+
2656
+ SUBMETHODS = (Calc_DischargeVolume_V2,)
2657
+ DERIVEDPARAMETERS = (sw1d_derived.Seconds,)
2658
+ REQUIREDSEQUENCES = (sw1d_fluxes.Outflow,)
2659
+ UPDATEDSEQUENCES = (sw1d_fluxes.DischargeVolume,)
2660
+
2661
+
2662
+ class Determine_MaxTimeStep_V1(modeltools.AutoMethod):
2663
+ """Interface method for determining the highest possible computation time step at a
2664
+ central location."""
2665
+
2666
+ SUBMETHODS = (
2667
+ Calc_WaterLevelUpstream_V1,
2668
+ Calc_WaterLevelDownstream_V1,
2669
+ Calc_WaterLevel_V1,
2670
+ Calc_WaterDepth_WettedArea_WettedPerimeter_V1,
2671
+ Calc_DischargeUpstream_V1,
2672
+ Calc_DischargeDownstream_V1,
2673
+ Calc_MaxTimeStep_V1,
2674
+ )
2675
+ CONTROLPARAMETERS = (sw1d_control.TimeStepFactor,)
2676
+ DERIVEDPARAMETERS = (sw1d_derived.WeightUpstream, sw1d_derived.LengthMin)
2677
+ FIXEDPARAMETERS = (sw1d_fixed.GravitationalAcceleration,)
2678
+ REQUIREDSEQUENCES = (sw1d_states.Discharge,)
2679
+ RESULTSEQUENCES = (
2680
+ sw1d_factors.WaterLevelUpstream,
2681
+ sw1d_factors.WaterLevelDownstream,
2682
+ sw1d_factors.WaterLevel,
2683
+ sw1d_factors.WaterDepth,
2684
+ sw1d_factors.WettedArea,
2685
+ sw1d_factors.WettedPerimeter,
2686
+ sw1d_factors.MaxTimeStep,
2687
+ sw1d_fluxes.DischargeUpstream,
2688
+ sw1d_fluxes.DischargeDownstream,
2689
+ )
2690
+
2691
+
2692
+ class Determine_MaxTimeStep_V2(modeltools.AutoMethod):
2693
+ """Interface method for determining the highest possible computation time step at
2694
+ an inflow location."""
2695
+
2696
+ SUBMETHODS = (
2697
+ Calc_WaterLevelDownstream_V1,
2698
+ Calc_WaterLevel_V2,
2699
+ Calc_WaterDepth_WettedArea_V1,
2700
+ Calc_MaxTimeStep_V2,
2701
+ )
2702
+ CONTROLPARAMETERS = (sw1d_control.LengthDownstream, sw1d_control.TimeStepFactor)
2703
+ REQUIREDSEQUENCES = (sw1d_fluxes.Inflow,)
2704
+ RESULTSEQUENCES = (
2705
+ sw1d_factors.WaterLevelDownstream,
2706
+ sw1d_factors.WaterLevel,
2707
+ sw1d_factors.WaterDepth,
2708
+ sw1d_factors.WettedArea,
2709
+ sw1d_factors.MaxTimeStep,
2710
+ )
2711
+
2712
+
2713
+ class Determine_MaxTimeStep_V3(modeltools.AutoMethod):
2714
+ """Interface method for determining the highest possible computation time step at
2715
+ an outflow weir."""
2716
+
2717
+ SUBMETHODS = (Calc_WaterLevelUpstream_V1, Calc_WaterLevel_V3, Calc_MaxTimeStep_V3)
2718
+ CONTROLPARAMETERS = (
2719
+ sw1d_control.CrestHeight,
2720
+ sw1d_control.FlowCoefficient,
2721
+ sw1d_control.TimeStepFactor,
2722
+ sw1d_control.LengthUpstream,
2723
+ )
2724
+ FIXEDPARAMETERS = (sw1d_fixed.GravitationalAcceleration,)
2725
+ RESULTSEQUENCES = (
2726
+ sw1d_factors.WaterLevelUpstream,
2727
+ sw1d_factors.WaterLevel,
2728
+ sw1d_factors.MaxTimeStep,
2729
+ )
2730
+
2731
+
2732
+ class Determine_MaxTimeStep_V4(modeltools.AutoMethod):
2733
+ """Interface method for determining the highest possible computation time step at
2734
+ an outflow location."""
2735
+
2736
+ SUBMETHODS = (
2737
+ Calc_WaterLevelUpstream_V1,
2738
+ Calc_WaterLevel_V3,
2739
+ Calc_WaterDepth_WettedArea_V1,
2740
+ Calc_MaxTimeStep_V4,
2741
+ )
2742
+ CONTROLPARAMETERS = (sw1d_control.LengthUpstream, sw1d_control.TimeStepFactor)
2743
+ REQUIREDSEQUENCES = (sw1d_fluxes.Outflow,)
2744
+ RESULTSEQUENCES = (
2745
+ sw1d_factors.WaterLevelUpstream,
2746
+ sw1d_factors.WaterLevel,
2747
+ sw1d_factors.WaterDepth,
2748
+ sw1d_factors.WettedArea,
2749
+ sw1d_factors.MaxTimeStep,
2750
+ )
2751
+
2752
+
2753
+ class Determine_MaxTimeStep_V5(modeltools.AutoMethod):
2754
+ """Interface method for determining the highest possible computation time step at
2755
+ an outflow gate."""
2756
+
2757
+ SUBMETHODS = (Calc_WaterLevelUpstream_V1, Calc_WaterLevel_V4, Calc_MaxTimeStep_V5)
2758
+ CONTROLPARAMETERS = (
2759
+ sw1d_control.BottomLevel,
2760
+ sw1d_control.GateHeight,
2761
+ sw1d_control.FlowCoefficient,
2762
+ sw1d_control.LengthUpstream,
2763
+ sw1d_control.TimeStepFactor,
2764
+ )
2765
+ FIXEDPARAMETERS = (sw1d_fixed.GravitationalAcceleration,)
2766
+ REQUIREDSEQUENCES = (sw1d_factors.WaterLevelDownstream,)
2767
+ RESULTSEQUENCES = (
2768
+ sw1d_factors.WaterLevelUpstream,
2769
+ sw1d_factors.WaterLevel,
2770
+ sw1d_factors.MaxTimeStep,
2771
+ )
2772
+
2773
+
2774
+ class Determine_MaxTimeStep_V6(modeltools.AutoMethod):
2775
+ """Interface method for determining the highest possible computation time step at
2776
+ an inflow and outflow location."""
2777
+
2778
+ SUBMETHODS = (
2779
+ Calc_WaterLevelUpstream_V1,
2780
+ Calc_WaterLevelDownstream_V1,
2781
+ Calc_WaterLevel_V1,
2782
+ Calc_WaterDepth_WettedArea_V1,
2783
+ Calc_MaxTimeStep_V6,
2784
+ )
2785
+ CONTROLPARAMETERS = (sw1d_control.TimeStepFactor,)
2786
+ DERIVEDPARAMETERS = (sw1d_derived.LengthMin, sw1d_derived.WeightUpstream)
2787
+ REQUIREDSEQUENCES = (sw1d_states.Discharge,)
2788
+ RESULTSEQUENCES = (
2789
+ sw1d_factors.WaterLevelDownstream,
2790
+ sw1d_factors.WaterLevelUpstream,
2791
+ sw1d_factors.WaterLevel,
2792
+ sw1d_factors.WaterDepth,
2793
+ sw1d_factors.WettedArea,
2794
+ sw1d_factors.MaxTimeStep,
2795
+ )
2796
+
2797
+
2798
+ class Determine_Discharge_V1(modeltools.AutoMethod):
2799
+ """Interface method for determining the discharge at a central location."""
2800
+
2801
+ SUBMETHODS = (
2802
+ Calc_WaterVolumeUpstream_V1,
2803
+ Calc_WaterVolumeDownstream_V1,
2804
+ Calc_Discharge_V1,
2805
+ Update_Discharge_V1,
2806
+ Update_DischargeVolume_V1,
2807
+ )
2808
+ CONTROLPARAMETERS = (
2809
+ sw1d_control.StricklerCoefficient,
2810
+ sw1d_control.DiffusionFactor,
2811
+ )
2812
+ DERIVEDPARAMETERS = (sw1d_derived.LengthMean,)
2813
+ FIXEDPARAMETERS = (sw1d_fixed.GravitationalAcceleration,)
2814
+ REQUIREDSEQUENCES = (
2815
+ sw1d_factors.WaterLevelUpstream,
2816
+ sw1d_factors.WaterLevelDownstream,
2817
+ sw1d_factors.WettedArea,
2818
+ sw1d_factors.WettedPerimeter,
2819
+ sw1d_fluxes.DischargeUpstream,
2820
+ sw1d_fluxes.DischargeDownstream,
2821
+ sw1d_factors.TimeStep,
2822
+ )
2823
+ RESULTSEQUENCES = (
2824
+ sw1d_factors.WaterVolumeUpstream,
2825
+ sw1d_factors.WaterVolumeDownstream,
2826
+ )
2827
+ UPDATEDSEQUENCES = (sw1d_states.Discharge, sw1d_fluxes.DischargeVolume)
2828
+
2829
+
2830
+ class Determine_Discharge_V2(modeltools.Method):
2831
+ """Interface method for determining the discharge at an inflow location."""
2832
+
2833
+ REQUIREDSEQUENCES = (sw1d_fluxes.Inflow,)
2834
+ UPDATEDSEQUENCES = (sw1d_states.Discharge,)
2835
+
2836
+ @staticmethod
2837
+ def __call__(model: modeltools.Model) -> None:
2838
+ flu = model.sequences.fluxes.fastaccess
2839
+ sta = model.sequences.states.fastaccess
2840
+ sta.discharge = flu.inflow
2841
+
2842
+
2843
+ class Determine_Discharge_V3(modeltools.AutoMethod):
2844
+ """Interface method for determining the discharge at an outflow weir."""
2845
+
2846
+ SUBMETHODS = (Calc_Discharge_V2, Update_DischargeVolume_V1)
2847
+ CONTROLPARAMETERS = (
2848
+ sw1d_control.CrestHeight,
2849
+ sw1d_control.CrestWidth,
2850
+ sw1d_control.FlowCoefficient,
2851
+ )
2852
+ FIXEDPARAMETERS = (sw1d_fixed.GravitationalAcceleration,)
2853
+ REQUIREDSEQUENCES = (sw1d_factors.WaterLevel, sw1d_factors.TimeStep)
2854
+ UPDATEDSEQUENCES = (sw1d_states.Discharge, sw1d_fluxes.DischargeVolume)
2855
+
2856
+
2857
+ class Determine_Discharge_V4(modeltools.Method):
2858
+ """Interface method for determining the discharge at an outflow location."""
2859
+
2860
+ REQUIREDSEQUENCES = (sw1d_fluxes.Outflow,)
2861
+ UPDATEDSEQUENCES = (sw1d_states.Discharge,)
2862
+
2863
+ @staticmethod
2864
+ def __call__(model: modeltools.Model) -> None:
2865
+ flu = model.sequences.fluxes.fastaccess
2866
+ sta = model.sequences.states.fastaccess
2867
+ sta.discharge = flu.outflow
2868
+
2869
+
2870
+ class Determine_Discharge_V5(modeltools.AutoMethod):
2871
+ """Interface method for determining the sluice-modified discharge at a central
2872
+ location considering."""
2873
+
2874
+ SUBMETHODS = (
2875
+ Calc_WaterVolumeUpstream_V1,
2876
+ Calc_WaterVolumeDownstream_V1,
2877
+ Calc_Discharge_V1,
2878
+ Update_Discharge_V1,
2879
+ Update_Discharge_V2,
2880
+ Update_DischargeVolume_V1,
2881
+ )
2882
+ CONTROLPARAMETERS = (
2883
+ sw1d_control.StricklerCoefficient,
2884
+ sw1d_control.DiffusionFactor,
2885
+ sw1d_control.BottomLowWaterThreshold,
2886
+ sw1d_control.UpperLowWaterThreshold,
2887
+ sw1d_control.BottomHighWaterThreshold,
2888
+ sw1d_control.UpperHighWaterThreshold,
2889
+ )
2890
+ DERIVEDPARAMETERS = (sw1d_derived.TOY, sw1d_derived.LengthMean)
2891
+ FIXEDPARAMETERS = (sw1d_fixed.GravitationalAcceleration,)
2892
+ REQUIREDSEQUENCES = (
2893
+ sw1d_factors.WaterLevelUpstream,
2894
+ sw1d_factors.WaterLevelDownstream,
2895
+ sw1d_factors.WettedArea,
2896
+ sw1d_factors.WettedPerimeter,
2897
+ sw1d_fluxes.DischargeUpstream,
2898
+ sw1d_fluxes.DischargeDownstream,
2899
+ sw1d_factors.TimeStep,
2900
+ )
2901
+ RESULTSEQUENCES = (
2902
+ sw1d_factors.WaterVolumeUpstream,
2903
+ sw1d_factors.WaterVolumeDownstream,
2904
+ )
2905
+ UPDATEDSEQUENCES = (sw1d_states.Discharge, sw1d_fluxes.DischargeVolume)
2906
+
2907
+
2908
+ class Determine_Discharge_V6(modeltools.AutoMethod):
2909
+ """Interface method for determining the discharge at an outflow gate."""
2910
+
2911
+ SUBMETHODS = (Calc_Discharge_V3, Update_DischargeVolume_V1)
2912
+ CONTROLPARAMETERS = (
2913
+ sw1d_control.BottomLevel,
2914
+ sw1d_control.GateHeight,
2915
+ sw1d_control.GateWidth,
2916
+ sw1d_control.FlowCoefficient,
2917
+ sw1d_control.DampingRadius,
2918
+ )
2919
+ FIXEDPARAMETERS = (sw1d_fixed.GravitationalAcceleration,)
2920
+ REQUIREDSEQUENCES = (
2921
+ sw1d_factors.WaterLevel,
2922
+ sw1d_factors.WaterLevelUpstream,
2923
+ sw1d_factors.WaterLevelDownstream,
2924
+ sw1d_factors.TimeStep,
2925
+ )
2926
+ UPDATEDSEQUENCES = (sw1d_states.Discharge, sw1d_fluxes.DischargeVolume)
2927
+
2928
+
2929
+ class Determine_Discharge_V7(modeltools.AutoMethod):
2930
+ """Interface method for determining the discharge at a pumping station."""
2931
+
2932
+ SUBMETHODS = (Calc_WaterLevel_V3, Calc_Discharge_V4, Update_DischargeVolume_V1)
2933
+ CONTROLPARAMETERS = (
2934
+ sw1d_control.Gradient2PumpingRate,
2935
+ sw1d_control.TargetWaterLevel1,
2936
+ sw1d_control.TargetWaterLevel2,
2937
+ )
2938
+ REQUIREDSEQUENCES = (
2939
+ sw1d_factors.WaterLevelUpstream,
2940
+ sw1d_factors.WaterLevelDownstream,
2941
+ sw1d_factors.TimeStep,
2942
+ )
2943
+ UPDATEDSEQUENCES = (sw1d_states.Discharge, sw1d_fluxes.DischargeVolume)
2944
+ RESULTSEQUENCES = (sw1d_factors.WaterLevel,)
2945
+
2946
+
2947
+ class Get_WaterVolume_V1(modeltools.Method):
2948
+ """Interface method for querying the water volume in 1000 m³."""
2949
+
2950
+ REQUIREDSEQUENCES = (sw1d_states.WaterVolume,)
2951
+
2952
+ @staticmethod
2953
+ def __call__(model: modeltools.Model) -> float:
2954
+ sta = model.sequences.states.fastaccess
2955
+ return sta.watervolume
2956
+
2957
+
2958
+ class Get_WaterLevel_V1(modeltools.Method):
2959
+ """Interface method for querying the water level in m."""
2960
+
2961
+ REQUIREDSEQUENCES = (sw1d_factors.WaterLevel,)
2962
+
2963
+ @staticmethod
2964
+ def __call__(model: modeltools.Model) -> float:
2965
+ fac = model.sequences.factors.fastaccess
2966
+ return fac.waterlevel
2967
+
2968
+
2969
+ class Get_Discharge_V1(modeltools.Method):
2970
+ """Interface method for querying the discharge in m³/s."""
2971
+
2972
+ REQUIREDSEQUENCES = (sw1d_states.Discharge,)
2973
+
2974
+ @staticmethod
2975
+ def __call__(model: modeltools.Model) -> float:
2976
+ sta = model.sequences.states.fastaccess
2977
+ return sta.discharge
2978
+
2979
+
2980
+ class Get_DischargeVolume_V1(modeltools.Method):
2981
+ """Interface method for querying the discharge in m³."""
2982
+
2983
+ REQUIREDSEQUENCES = (sw1d_fluxes.DischargeVolume,)
2984
+
2985
+ @staticmethod
2986
+ def __call__(model: modeltools.Model) -> float:
2987
+ flu = model.sequences.fluxes.fastaccess
2988
+ return flu.dischargevolume
2989
+
2990
+
2991
+ class Get_MaxTimeStep_V1(modeltools.Method):
2992
+ """Interface method for querying the highest possible computation time step in
2993
+ s."""
2994
+
2995
+ REQUIREDSEQUENCES = (sw1d_factors.MaxTimeStep,)
2996
+
2997
+ @staticmethod
2998
+ def __call__(model: modeltools.Model) -> float:
2999
+ fac = model.sequences.factors.fastaccess
3000
+ return fac.maxtimestep
3001
+
3002
+
3003
+ class Set_TimeStep_V1(modeltools.Method):
3004
+ """Interface method for setting the actual computation time step in s."""
3005
+
3006
+ RESULTSEQUENCES = (sw1d_factors.TimeStep,)
3007
+
3008
+ @staticmethod
3009
+ def __call__(model: modeltools.Model, timestep: float) -> None:
3010
+ fac = model.sequences.factors.fastaccess
3011
+ fac.timestep = timestep
3012
+
3013
+
3014
+ class Get_PartialDischargeUpstream_V1(modeltools.Method):
3015
+ r"""Return a partial discharge estimate suitable for a downstream model.
3016
+
3017
+ Basic equation:
3018
+ :math:`PartialDischargeUpstream = Discharge_{server} \cdot
3019
+ \frac{|Discharge_{client}|}{\Sigma_{i=1}^{n_{downstream}} |Discharge_i|}`
3020
+
3021
+ Examples:
3022
+
3023
+ If the client model (which is currently asking for the partial discharge) is
3024
+ the only downstream model, |Get_PartialDischargeUpstream_V1| returns the total
3025
+ discharge without modification:
3026
+
3027
+ >>> from hydpy import Element, Node, prepare_model, round_
3028
+ >>> n01 = Node("n01", variable="LongQ")
3029
+ >>> e0 = Element("e0", outlets=n01)
3030
+ >>> e1a = Element("e1a", inlets=n01)
3031
+
3032
+ >>> c0 = prepare_model("sw1d_channel")
3033
+ >>> e0.model = c0
3034
+ >>> c0.parameters.control.nmbsegments(1)
3035
+ >>> with c0.add_routingmodel_v2("sw1d_lias", position=0, update=False) as r0:
3036
+ ... states.discharge = 5.0
3037
+ >>> with c0.add_storagemodel_v1("sw1d_storage", position=0, update=False):
3038
+ ... pass
3039
+
3040
+ >>> c1a = prepare_model("sw1d_channel")
3041
+ >>> e1a.model = c1a
3042
+ >>> c1a.parameters.control.nmbsegments(1)
3043
+ >>> with c1a.add_routingmodel_v2("sw1d_lias", position=0, update=False) as r1a:
3044
+ ... states.discharge = 3.0
3045
+ >>> with c1a.add_storagemodel_v1("sw1d_storage", position=0, update=False):
3046
+ ... pass
3047
+ >>> network = c0.couple_models(nodes=[n01], elements=[e0, e1a])
3048
+ >>> round_(r0.get_partialdischargeupstream_v1(3.0))
3049
+ 5.0
3050
+
3051
+ For multiple downstream models, it returns the discharge portion that it
3052
+ attributes to the current client model:
3053
+
3054
+ >>> e1b = Element("e1b", inlets=n01)
3055
+ >>> c1b = prepare_model("sw1d_channel")
3056
+ >>> e1b.model = c1b
3057
+ >>> c1b.parameters.control.nmbsegments(1)
3058
+ >>> with c1b.add_routingmodel_v2("sw1d_lias", position=0, update=False) as r1b:
3059
+ ... states.discharge = 1.0
3060
+ >>> with c1b.add_storagemodel_v1("sw1d_storage", position=0, update=False):
3061
+ ... pass
3062
+ >>> network = c0.couple_models(nodes=[n01], elements=[e0, e1a, e1b])
3063
+ >>> round_(r0.get_partialdischargeupstream_v1(3.0))
3064
+ 3.75
3065
+ >>> round_(r0.get_partialdischargeupstream_v1(1.0))
3066
+ 1.25
3067
+
3068
+ To prevent zero divisions, |Get_PartialDischargeUpstream_V1| returns zero if
3069
+ all downstream models' (total) discharge is also zero:
3070
+
3071
+ >>> r1a.sequences.states.discharge = 0.0
3072
+ >>> r1b.sequences.states.discharge = 0.0
3073
+ >>> round_(r0.get_partialdischargeupstream_v1(0.0))
3074
+ 0.0
3075
+
3076
+ .. testsetup::
3077
+
3078
+ >>> Node.clear_all()
3079
+ >>> Element.clear_all()
3080
+ """
3081
+
3082
+ SUBMODELINTERFACES = (
3083
+ routinginterfaces.RoutingModel_V2,
3084
+ routinginterfaces.RoutingModel_V3,
3085
+ )
3086
+ REQUIREDSEQUENCES = (sw1d_states.Discharge,)
3087
+
3088
+ @staticmethod
3089
+ def __call__(model: modeltools.Model, clientdischarge: float) -> float:
3090
+ sta = model.sequences.states.fastaccess
3091
+
3092
+ dischargedownstream: float = 0.0
3093
+ for i in range(model.routingmodelsdownstream.number):
3094
+ if model.routingmodelsdownstream.typeids[i] in (2, 3):
3095
+ dischargedownstream += modelutils.fabs(
3096
+ cast(
3097
+ RoutingModels_V2_V3, model.routingmodelsdownstream.submodels[i]
3098
+ ).get_discharge()
3099
+ )
3100
+ if dischargedownstream == 0.0:
3101
+ return 0.0
3102
+ return modelutils.fabs(sta.discharge) * clientdischarge / dischargedownstream
3103
+
3104
+
3105
+ class Get_PartialDischargeDownstream_V1(modeltools.Method):
3106
+ r"""Return a partial discharge estimate suitable for an upstream model.
3107
+
3108
+ Basic equation:
3109
+ :math:`PartialDischargeDownstream = Discharge_{server} \cdot
3110
+ \frac{|Discharge_{client}|}{\Sigma_{i=1}^{n_{upstream}} |Discharge_i|}`
3111
+
3112
+ Examples:
3113
+
3114
+ If the client model (which is currently asking for the partial discharge) is
3115
+ the only upstream model, |Get_PartialDischargeDownstream_V1| returns the total
3116
+ discharge without modification:
3117
+
3118
+ >>> from hydpy import Element, Node, prepare_model, round_
3119
+ >>> n01 = Node("n01", variable="LongQ")
3120
+ >>> e1 = Element("e1", inlets=n01)
3121
+ >>> e0a = Element("e0a", outlets=n01)
3122
+
3123
+ >>> c1 = prepare_model("sw1d_channel")
3124
+ >>> e1.model = c1
3125
+ >>> c1.parameters.control.nmbsegments(1)
3126
+ >>> with c1.add_storagemodel_v1("sw1d_storage", position=0, update=False):
3127
+ ... pass
3128
+ >>> with c1.add_routingmodel_v2("sw1d_lias", position=1, update=False) as r1:
3129
+ ... states.discharge = 5.0
3130
+
3131
+ >>> c0a = prepare_model("sw1d_channel")
3132
+ >>> e0a.model = c0a
3133
+ >>> c0a.parameters.control.nmbsegments(1)
3134
+ >>> with c0a.add_storagemodel_v1("sw1d_storage", position=0, update=False):
3135
+ ... pass
3136
+ >>> with c0a.add_routingmodel_v2("sw1d_lias", position=1, update=False) as r0a:
3137
+ ... states.discharge = 3.0
3138
+ >>> network = c1.couple_models(nodes=[n01], elements=[e1, e0a])
3139
+ >>> round_(r1.get_partialdischargedownstream_v1(3.0))
3140
+ 5.0
3141
+
3142
+ For multiple upstream models, it returns the discharge portion that it
3143
+ attributes to the current client model:
3144
+
3145
+ >>> e0b = Element("e0b", outlets=n01)
3146
+ >>> c0b = prepare_model("sw1d_channel")
3147
+ >>> e0b.model = c0b
3148
+ >>> c0b.parameters.control.nmbsegments(1)
3149
+ >>> with c0b.add_storagemodel_v1("sw1d_storage", position=0, update=False):
3150
+ ... pass
3151
+ >>> with c0b.add_routingmodel_v2("sw1d_lias", position=1, update=False) as r0b:
3152
+ ... states.discharge = 1.0
3153
+ >>> network = c1.couple_models(nodes=[n01], elements=[e1, e0a, e0b])
3154
+ >>> round_(r1.get_partialdischargedownstream_v1(3.0))
3155
+ 3.75
3156
+ >>> round_(r1.get_partialdischargedownstream_v1(1.0))
3157
+ 1.25
3158
+
3159
+ To prevent zero divisions, |Get_PartialDischargeDownstream_V1| returns zero if
3160
+ all upstream models' (total) discharge is also zero:
3161
+
3162
+ >>> r0a.sequences.states.discharge = 0.0
3163
+ >>> r0b.sequences.states.discharge = 0.0
3164
+ >>> round_(r1.get_partialdischargedownstream_v1(0.0))
3165
+ 0.0
3166
+
3167
+ .. testsetup::
3168
+
3169
+ >>> Node.clear_all()
3170
+ >>> Element.clear_all()
3171
+ """
3172
+
3173
+ SUBMODELINTERFACES = (
3174
+ routinginterfaces.RoutingModel_V1,
3175
+ routinginterfaces.RoutingModel_V2,
3176
+ )
3177
+ REQUIREDSEQUENCES = (sw1d_states.Discharge,)
3178
+
3179
+ @staticmethod
3180
+ def __call__(model: modeltools.Model, clientdischarge: float) -> float:
3181
+ sta = model.sequences.states.fastaccess
3182
+
3183
+ dischargeupstream: float = 0.0
3184
+ for i in range(model.routingmodelsupstream.number):
3185
+ if model.routingmodelsupstream.typeids[i] in (1, 2):
3186
+ dischargeupstream += modelutils.fabs(
3187
+ cast(
3188
+ RoutingModels_V1_V2, model.routingmodelsupstream.submodels[i]
3189
+ ).get_discharge()
3190
+ )
3191
+ if dischargeupstream == 0.0:
3192
+ return 0.0
3193
+ return modelutils.fabs(sta.discharge) * clientdischarge / dischargeupstream
3194
+
3195
+
3196
+ class Update_Storage_V1(modeltools.AutoMethod):
3197
+ """Interface method for updating the storage water content."""
3198
+
3199
+ SUBMETHODS = (
3200
+ Calc_NetInflow_V1,
3201
+ Update_WaterVolume_V1,
3202
+ Calc_WaterDepth_WaterLevel_V1,
3203
+ )
3204
+ CONTROLPARAMETERS = (sw1d_control.Length,)
3205
+ REQUIREDSEQUENCES = (sw1d_factors.TimeStep, sw1d_fluxes.LateralFlow)
3206
+ RESULTSEQUENCES = (
3207
+ sw1d_fluxes.NetInflow,
3208
+ sw1d_factors.WaterDepth,
3209
+ sw1d_factors.WaterLevel,
3210
+ )
3211
+ UPDATEDSEQUENCES = (sw1d_states.WaterVolume,)
3212
+
3213
+
3214
+ class Model(modeltools.SubstepModel):
3215
+ """|sw1d.DOCNAME.complete|."""
3216
+
3217
+ DOCNAME = modeltools.DocName(short="SW1D")
3218
+ __HYDPY_ROOTMODEL__ = None
3219
+
3220
+ INLET_METHODS = (
3221
+ Pick_Inflow_V1,
3222
+ Pick_Outflow_V1,
3223
+ Pick_LateralFlow_V1,
3224
+ Pick_WaterLevelDownstream_V1,
3225
+ Trigger_Preprocessing_V1,
3226
+ )
3227
+ RECEIVER_METHODS = ()
3228
+ RUN_METHODS = (
3229
+ Calc_MaxTimeSteps_V1,
3230
+ Calc_TimeStep_V1,
3231
+ Send_TimeStep_V1,
3232
+ Calc_Discharges_V1,
3233
+ Update_Storages_V1,
3234
+ Query_WaterLevels_V1,
3235
+ )
3236
+ INTERFACE_METHODS = (
3237
+ Perform_Preprocessing_V1,
3238
+ Perform_Preprocessing_V2,
3239
+ Perform_Preprocessing_V3,
3240
+ Perform_Preprocessing_V4,
3241
+ Perform_Preprocessing_V5,
3242
+ Perform_Postprocessing_V1,
3243
+ Perform_Postprocessing_V2,
3244
+ Perform_Postprocessing_V3,
3245
+ Perform_Postprocessing_V4,
3246
+ Determine_MaxTimeStep_V1,
3247
+ Determine_MaxTimeStep_V2,
3248
+ Determine_MaxTimeStep_V3,
3249
+ Determine_MaxTimeStep_V4,
3250
+ Determine_MaxTimeStep_V5,
3251
+ Determine_MaxTimeStep_V6,
3252
+ Determine_Discharge_V1,
3253
+ Determine_Discharge_V2,
3254
+ Determine_Discharge_V3,
3255
+ Determine_Discharge_V4,
3256
+ Determine_Discharge_V5,
3257
+ Determine_Discharge_V6,
3258
+ Determine_Discharge_V7,
3259
+ Get_WaterVolume_V1,
3260
+ Get_WaterLevel_V1,
3261
+ Get_Discharge_V1,
3262
+ Get_DischargeVolume_V1,
3263
+ Get_MaxTimeStep_V1,
3264
+ Set_TimeStep_V1,
3265
+ Get_PartialDischargeUpstream_V1,
3266
+ Get_PartialDischargeDownstream_V1,
3267
+ Update_Storage_V1,
3268
+ )
3269
+ ADD_METHODS = (
3270
+ Calc_MaxTimeStep_V1,
3271
+ Calc_MaxTimeStep_V2,
3272
+ Calc_MaxTimeStep_V3,
3273
+ Calc_MaxTimeStep_V4,
3274
+ Calc_MaxTimeStep_V5,
3275
+ Calc_MaxTimeStep_V6,
3276
+ Calc_WaterVolumeUpstream_V1,
3277
+ Calc_WaterVolumeDownstream_V1,
3278
+ Calc_WaterLevelUpstream_V1,
3279
+ Calc_WaterLevelDownstream_V1,
3280
+ Calc_WaterLevel_V1,
3281
+ Calc_WaterLevel_V2,
3282
+ Calc_WaterLevel_V3,
3283
+ Calc_WaterLevel_V4,
3284
+ Calc_WaterDepth_WaterLevel_CrossSectionModel_V2,
3285
+ Calc_WaterDepth_WaterLevel_V1,
3286
+ Calc_WaterDepth_WettedArea_CrossSectionModel_V2,
3287
+ Calc_WaterDepth_WettedArea_V1,
3288
+ Calc_WaterDepth_WettedArea_WettedPerimeter_CrossSectionModel_V2,
3289
+ Calc_WaterDepth_WettedArea_WettedPerimeter_V1,
3290
+ Calc_DischargeUpstream_V1,
3291
+ Calc_DischargeDownstream_V1,
3292
+ Calc_Discharge_V1,
3293
+ Calc_Discharge_V2,
3294
+ Calc_Discharge_V3,
3295
+ Calc_Discharge_V4,
3296
+ Update_Discharge_V1,
3297
+ Update_Discharge_V2,
3298
+ Reset_DischargeVolume_V1,
3299
+ Update_DischargeVolume_V1,
3300
+ Calc_DischargeVolume_V1,
3301
+ Calc_DischargeVolume_V2,
3302
+ Calc_NetInflow_V1,
3303
+ Update_WaterVolume_V1,
3304
+ )
3305
+ OUTLET_METHODS = (
3306
+ Pass_Discharge_V1,
3307
+ Pass_WaterLevel_V1,
3308
+ Trigger_Postprocessing_V1,
3309
+ Calc_Discharges_V2,
3310
+ )
3311
+ SENDER_METHODS = ()
3312
+ SUBMODELINTERFACES = (
3313
+ routinginterfaces.CrossSectionModel_V2,
3314
+ routinginterfaces.ChannelModel_V1,
3315
+ routinginterfaces.StorageModel_V1,
3316
+ routinginterfaces.RoutingModel_V1,
3317
+ routinginterfaces.RoutingModel_V2,
3318
+ routinginterfaces.RoutingModel_V3,
3319
+ )
3320
+ SUBMODELS = ()
3321
+
3322
+ crosssection = modeltools.SubmodelProperty(routinginterfaces.CrossSectionModel_V2)
3323
+ crosssection_is_mainmodel = modeltools.SubmodelIsMainmodelProperty()
3324
+ crosssection_typeid = modeltools.SubmodelTypeIDProperty()
3325
+
3326
+ channelmodels = modeltools.SubmodelsProperty(routinginterfaces.ChannelModel_V1)
3327
+ storagemodels = modeltools.SubmodelsProperty(routinginterfaces.StorageModel_V1)
3328
+ routingmodels = modeltools.SubmodelsProperty(routinginterfaces.RoutingModel_V1)
3329
+
3330
+ storagemodelupstream = modeltools.SubmodelProperty(
3331
+ routinginterfaces.StorageModel_V1
3332
+ )
3333
+ storagemodelupstream_is_mainmodel = modeltools.SubmodelIsMainmodelProperty()
3334
+ storagemodelupstream_typeid = modeltools.SubmodelTypeIDProperty()
3335
+
3336
+ storagemodeldownstream = modeltools.SubmodelProperty(
3337
+ routinginterfaces.StorageModel_V1
3338
+ )
3339
+ storagemodeldownstream_is_mainmodel = modeltools.SubmodelIsMainmodelProperty()
3340
+ storagemodeldownstream_typeid = modeltools.SubmodelTypeIDProperty()
3341
+
3342
+ routingmodelsupstream = modeltools.SubmodelsProperty(
3343
+ routinginterfaces.RoutingModel_V1,
3344
+ routinginterfaces.RoutingModel_V2,
3345
+ routinginterfaces.RoutingModel_V3,
3346
+ sidemodels=True,
3347
+ )
3348
+ routingmodelsdownstream = modeltools.SubmodelsProperty(
3349
+ routinginterfaces.RoutingModel_V2,
3350
+ routinginterfaces.RoutingModel_V3,
3351
+ routinginterfaces.RoutingModel_V3,
3352
+ sidemodels=True,
3353
+ )
3354
+
3355
+
3356
+ class Main_CrossSectionModel_V2(modeltools.AdHocModel):
3357
+ """Base class for |sw1d.DOCNAME.long| models that use submodels named
3358
+ `crosssection` and comply with the |CrossSectionModel_V2| interface."""
3359
+
3360
+ crosssection: modeltools.SubmodelProperty[routinginterfaces.CrossSectionModel_V2]
3361
+ crosssection_is_mainmodel = modeltools.SubmodelIsMainmodelProperty()
3362
+ crosssection_typeid = modeltools.SubmodelTypeIDProperty()
3363
+
3364
+ @importtools.prepare_submodel(
3365
+ "crosssection", routinginterfaces.CrossSectionModel_V2
3366
+ )
3367
+ def add_crosssection_v2(
3368
+ self, crosssection: routinginterfaces.CrossSectionModel_V2, /, *, refresh: bool
3369
+ ) -> None:
3370
+ """Initialise the given submodel that follows the |CrossSectionModel_V1|
3371
+ interface and is responsible for calculating discharge and related properties.
3372
+
3373
+ >>> from hydpy.models.sw1d_storage import *
3374
+ >>> parameterstep()
3375
+ >>> with model.add_crosssection_v2("wq_trapeze"):
3376
+ ... nmbtrapezes(2)
3377
+ ... bottomlevels(1.0, 3.0)
3378
+ ... bottomwidths(2.0)
3379
+ ... sideslopes(2.0, 4.0)
3380
+
3381
+ >>> model.crosssection.parameters.control.nmbtrapezes
3382
+ nmbtrapezes(2)
3383
+ >>> model.crosssection.parameters.control.bottomlevels
3384
+ bottomlevels(1.0, 3.0)
3385
+ """