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,3755 @@
1
+ """
2
+ .. _`Pegasus method`: https://link.springer.com/article/10.1007/BF01932959
3
+ """
4
+
5
+ # import...
6
+ # ...from site-packages
7
+ import numpy
8
+
9
+ # ...from HydPy
10
+ from hydpy import config
11
+ from hydpy.core import importtools
12
+ from hydpy.core import exceptiontools
13
+ from hydpy.core import modeltools
14
+ from hydpy.core import objecttools
15
+ from hydpy.core.typingtools import *
16
+ from hydpy.auxs import quadtools
17
+ from hydpy.auxs import roottools
18
+ from hydpy.cythons import modelutils
19
+ from hydpy.cythons import smoothutils
20
+ from hydpy.interfaces import dischargeinterfaces
21
+ from hydpy.interfaces import petinterfaces
22
+ from hydpy.interfaces import precipinterfaces
23
+ from hydpy.interfaces import stateinterfaces
24
+ from hydpy.interfaces import tempinterfaces
25
+
26
+ # ...from wland
27
+ from hydpy.models.wland import wland_control
28
+ from hydpy.models.wland import wland_derived
29
+ from hydpy.models.wland import wland_fixed
30
+ from hydpy.models.wland import wland_solver
31
+ from hydpy.models.wland import wland_inputs
32
+ from hydpy.models.wland import wland_factors
33
+ from hydpy.models.wland import wland_fluxes
34
+ from hydpy.models.wland import wland_states
35
+ from hydpy.models.wland import wland_aides
36
+ from hydpy.models.wland import wland_outlets
37
+ from hydpy.models.wland import wland_constants
38
+ from hydpy.models.wland.wland_constants import CONIFER, DECIDIOUS, SEALED, SOIL, MIXED
39
+
40
+
41
+ class Pick_HS_V1(modeltools.Method):
42
+ r"""Take the surface water level from a submodel that complies with the
43
+ |WaterLevelModel_V1| interface, if available.
44
+
45
+ Basic equation:
46
+ :math:`HS = 1000 \cdot (WaterLevel - BL)`
47
+
48
+ Examples:
49
+
50
+ >>> from hydpy.models.wland_wag import *
51
+ >>> parameterstep()
52
+
53
+ Without an available submodel, |Pick_HS_V1| does not change the current value
54
+ of sequence |HS| and sets |DHS| (the change of |HS|) accordingly to zero:
55
+
56
+ >>> states.hs(3000.0)
57
+ >>> model.pick_hs_v1()
58
+ >>> states.hs
59
+ hs(3000.0)
60
+ >>> factors.dhs
61
+ dhs(0.0)
62
+
63
+ We take |exch_waterlevel| as an example to demonstrate that |Pick_HS_V1|
64
+ correctly uses submodels that follow the |WaterLevelModel_V1| interface and the
65
+ defined channel bottom level (|BL|) for updating |HS| and logs such changes via
66
+ sequence |DHS|:
67
+
68
+ >>> bl(3.0)
69
+ >>> with model.add_waterlevelmodel_v1("exch_waterlevel"):
70
+ ... pass
71
+ >>> from hydpy import Element, Node
72
+ >>> wl = Node("wl", variable="WaterLevel")
73
+ >>> wl.sequences.sim = 5.0
74
+ >>> e = Element("e", receivers=wl, outlets="q")
75
+ >>> e.model = model
76
+ >>> model.pick_hs_v1()
77
+ >>> states.hs
78
+ hs(2000.0)
79
+ >>> factors.dhs
80
+ dhs(-1000.0)
81
+ """
82
+
83
+ CONTROLPARAMETERS = (wland_control.BL,)
84
+ UPDATEDSEQUENCES = (wland_states.HS,)
85
+ RESULTSEQUENCES = (wland_factors.DHS,)
86
+
87
+ @staticmethod
88
+ def __call__(model: modeltools.Model) -> None:
89
+ con = model.parameters.control.fastaccess
90
+ fac = model.sequences.factors.fastaccess
91
+ old = model.sequences.states.fastaccess_old
92
+ new = model.sequences.states.fastaccess_new
93
+ if model.waterlevelmodel is None:
94
+ fac.dhs = 0.0
95
+ elif model.waterlevelmodel_typeid == 1:
96
+ waterlevel: float = cast(
97
+ stateinterfaces.WaterLevelModel_V1, model.waterlevelmodel
98
+ ).get_waterlevel()
99
+ hs: float = 1000.0 * (waterlevel - con.bl)
100
+ fac.dhs = hs - new.hs
101
+ old.hs = new.hs = hs
102
+
103
+
104
+ class Calc_FXS_V1(modeltools.Method):
105
+ r"""Query the current surface water supply/extraction.
106
+
107
+ Basic equation:
108
+ .. math::
109
+ FXS_{fluxes} = \begin{cases}
110
+ 0 &|\ FXS_{inputs} = 0
111
+ \\
112
+ \frac{FXS_{inputs}}{ASR} &|\ FXS_{inputs} \neq 0 \land NU > 1
113
+ \\
114
+ inf &|\ FXS_{inputs} \neq 0 \land NU = 1
115
+ \end{cases}
116
+
117
+ Examples:
118
+
119
+ >>> from hydpy.models.wland import *
120
+ >>> parameterstep()
121
+ >>> nu(2)
122
+ >>> derived.asr(0.5)
123
+ >>> inputs.fxs = 2.0
124
+ >>> model.calc_fxs_v1()
125
+ >>> fluxes.fxs
126
+ fxs(4.0)
127
+ >>> nu(1)
128
+ >>> derived.asr(0.0)
129
+ >>> model.calc_fxs_v1()
130
+ >>> fluxes.fxs
131
+ fxs(inf)
132
+ >>> inputs.fxs = 0.0
133
+ >>> model.calc_fxs_v1()
134
+ >>> fluxes.fxs
135
+ fxs(0.0)
136
+ """
137
+
138
+ CONTROLPARAMETERS = (wland_control.NU,)
139
+ DERIVEDPARAMETERS = (wland_derived.ASR,)
140
+ REQUIREDSEQUENCES = (wland_inputs.FXS,)
141
+ RESULTSEQUENCES = (wland_fluxes.FXS,)
142
+
143
+ @staticmethod
144
+ def __call__(model: modeltools.Model) -> None:
145
+ con = model.parameters.control.fastaccess
146
+ der = model.parameters.derived.fastaccess
147
+ inp = model.sequences.inputs.fastaccess
148
+ flu = model.sequences.fluxes.fastaccess
149
+ if inp.fxs == 0.0:
150
+ flu.fxs = 0.0
151
+ elif con.nu == 1:
152
+ flu.fxs = modelutils.inf
153
+ else:
154
+ flu.fxs = inp.fxs / der.asr
155
+
156
+
157
+ class Calc_FXG_V1(modeltools.Method):
158
+ r"""Query the current seepage/extraction.
159
+
160
+ Basic equation:
161
+ .. math::
162
+ FXG_{fluxes} = \begin{cases}
163
+ 0 &|\ FXG_{inputs} = 0
164
+ \\
165
+ \frac{FXG_{inputs}}{AGR} &|\ FXG_{inputs} \neq 0 \land AGR > 0
166
+ \\
167
+ inf &|\ FXG_{inputs} \neq 0 \land AGR = 0
168
+ \end{cases}
169
+
170
+ Examples:
171
+
172
+ >>> from hydpy.models.wland import *
173
+ >>> parameterstep()
174
+ >>> derived.agr(0.4)
175
+ >>> inputs.fxg = 2.0
176
+ >>> model.calc_fxg_v1()
177
+ >>> fluxes.fxg
178
+ fxg(5.0)
179
+ >>> derived.agr(0.0)
180
+ >>> model.calc_fxg_v1()
181
+ >>> fluxes.fxg
182
+ fxg(inf)
183
+ >>> inputs.fxg = 0.0
184
+ >>> model.calc_fxg_v1()
185
+ >>> fluxes.fxg
186
+ fxg(0.0)
187
+ """
188
+
189
+ DERIVEDPARAMETERS = (wland_derived.AGR,)
190
+ REQUIREDSEQUENCES = (wland_inputs.FXG,)
191
+ RESULTSEQUENCES = (wland_fluxes.FXG,)
192
+
193
+ @staticmethod
194
+ def __call__(model: modeltools.Model) -> None:
195
+ der = model.parameters.derived.fastaccess
196
+ inp = model.sequences.inputs.fastaccess
197
+ flu = model.sequences.fluxes.fastaccess
198
+ if inp.fxg == 0.0:
199
+ flu.fxg = 0.0
200
+ else:
201
+ ra: float = der.agr
202
+ if ra > 0.0:
203
+ flu.fxg = inp.fxg / ra
204
+ else:
205
+ flu.fxg = modelutils.inf
206
+
207
+
208
+ class Calc_PC_V1(modeltools.Method):
209
+ r"""Calculate the corrected precipitation.
210
+
211
+ Basic equation:
212
+ :math:`PC = CP \cdot P`
213
+
214
+ Examples:
215
+
216
+ >>> from hydpy.models.wland import *
217
+ >>> parameterstep()
218
+ >>> cp(1.2)
219
+ >>> inputs.p = 2.0
220
+ >>> model.calc_pc_v1()
221
+ >>> fluxes.pc
222
+ pc(2.4)
223
+ """
224
+
225
+ CONTROLPARAMETERS = (wland_control.CP,)
226
+ REQUIREDSEQUENCES = (wland_inputs.P,)
227
+ RESULTSEQUENCES = (wland_fluxes.PC,)
228
+
229
+ @staticmethod
230
+ def __call__(model: modeltools.Model) -> None:
231
+ con = model.parameters.control.fastaccess
232
+ inp = model.sequences.inputs.fastaccess
233
+ flu = model.sequences.fluxes.fastaccess
234
+ flu.pc = con.cp * inp.p
235
+
236
+
237
+ class Calc_PE_PET_PETModel_V1(modeltools.Method):
238
+ """Let a submodel that complies with the |PETModel_V1| interface calculate the
239
+ potential evapotranspiration of the land areas and the potential evaporation of the
240
+ surface water storage.
241
+
242
+ Example:
243
+
244
+ We use |evap_ret_tw2002| as an example:
245
+
246
+ >>> from hydpy.models.wland_wag import *
247
+ >>> parameterstep()
248
+ >>> nu(4)
249
+ >>> at(1.0)
250
+ >>> aur(0.25, 0.15, 0.1, 0.5)
251
+ >>> lt(FIELD, FIELD, FIELD, WATER)
252
+ >>> derived.nul.update()
253
+ >>> from hydpy import prepare_model
254
+ >>> with model.add_petmodel_v1("evap_ret_tw2002"):
255
+ ... hrualtitude(200.0, 600.0, 1000.0, 100.0)
256
+ ... coastfactor(0.6)
257
+ ... evapotranspirationfactor(1.1)
258
+ ... with model.add_radiationmodel_v2("meteo_glob_io"):
259
+ ... inputs.globalradiation = 200.0
260
+ ... with model.add_tempmodel_v2("meteo_temp_io"):
261
+ ... temperatureaddend(1.0)
262
+ ... inputs.temperature = 14.0
263
+ >>> model.calc_pe_pet_v1()
264
+ >>> fluxes.pe
265
+ pe(3.07171, 2.86215, 2.86215, 3.128984)
266
+ >>> fluxes.pet
267
+ pet(3.07171, 2.86215, 2.86215, 0.0)
268
+ """
269
+
270
+ DERIVEDPARAMETERS = (wland_derived.NUL,)
271
+ RESULTSEQUENCES = (wland_fluxes.PE, wland_fluxes.PET)
272
+
273
+ @staticmethod
274
+ def __call__(model: modeltools.Model, submodel: petinterfaces.PETModel_V1) -> None:
275
+ der = model.parameters.derived.fastaccess
276
+ flu = model.sequences.fluxes.fastaccess
277
+ submodel.determine_potentialevapotranspiration()
278
+ for k in range(der.nul):
279
+ flu.pe[k] = flu.pet[k] = submodel.get_potentialevapotranspiration(k)
280
+ flu.pe[der.nul] = submodel.get_potentialevapotranspiration(der.nul)
281
+ flu.pet[der.nul] = 0.0
282
+
283
+
284
+ class Calc_PE_PET_PETModel_V2(modeltools.Method):
285
+ """Let a submodel that complies with the |PETModel_V2| interface calculate the
286
+ potential interception evaporation and potential vadose zone evapotranspiration of
287
+ the land areas and the potential evaporation of the surface water storage.
288
+
289
+ Examples:
290
+
291
+ We use |evap_pet_ambav1| as an example. All data stems from the integration
292
+ tests :ref:`evap_pet_ambav1_vegetation_daily`,
293
+ :ref:`evap_pet_ambav1_snow_daily`, and :ref:`evap_pet_ambav1_water_area_daily`:
294
+
295
+ >>> from hydpy import pub
296
+ >>> pub.timegrids = "2000-08-01", "2000-08-02", "1d"
297
+ >>> from hydpy.models.wland_wag import *
298
+ >>> parameterstep("1h")
299
+ >>> nu(3)
300
+ >>> at(1.0)
301
+ >>> aur(0.5, 0.3, 0.2)
302
+ >>> lt(FIELD, DECIDIOUS, WATER)
303
+ >>> lai(5.0)
304
+ >>> derived.nul.update()
305
+ >>> inputs.t = 15.0
306
+ >>> inputs.p = 0.0
307
+ >>> states.sp = 0.0, 1.0, 0.0
308
+ >>> from hydpy import prepare_model
309
+ >>> with model.add_petmodel_v2("evap_pet_ambav1") as ambav:
310
+ ... measuringheightwindspeed(10.0)
311
+ ... leafalbedo(0.2)
312
+ ... leafalbedosnow(0.8)
313
+ ... groundalbedo(0.2)
314
+ ... groundalbedosnow(0.8)
315
+ ... cropheight.field = 10.0
316
+ ... cropheight.decidious = 10.0
317
+ ... cropheight.water = 0.0
318
+ ... leafresistance(40.0)
319
+ ... wetsoilresistance(100.0)
320
+ ... soilresistanceincrease(1.0)
321
+ ... wetnessthreshold(0.5)
322
+ ... cloudtypefactor(0.2)
323
+ ... nightcloudfactor(1.0)
324
+ ... inputs.windspeed = 2.0
325
+ ... inputs.relativehumidity = 80.0
326
+ ... inputs.atmosphericpressure = 1000.0
327
+ ... states.soilresistance = 100.0
328
+ ... with model.add_radiationmodel_v4("meteo_psun_sun_glob_io"):
329
+ ... inputs.sunshineduration = 6.0
330
+ ... inputs.possiblesunshineduration = 16.0
331
+ ... inputs.globalradiation = 190.0
332
+
333
+ The first example reproduces the results for the first simulated day of the
334
+ integration tests :ref:`evap_pet_ambav1_vegetation_daily` (first response
335
+ unit) and :ref:`evap_pet_ambav1_water_area_daily` (third response unit):
336
+
337
+ >>> ambav.sequences.logs.loggedprecipitation = [0.0]
338
+ >>> ambav.sequences.logs.loggedpotentialsoilevapotranspiration = [1.0]
339
+ >>> model.calc_pe_pet_v1()
340
+ >>> fluxes.pe
341
+ pe(3.301949, 1.146759, 1.890672)
342
+ >>> fluxes.pet
343
+ pet(2.292368, 0.796134, 0.0)
344
+
345
+ The second example reproduces the results for the third simulated day of the
346
+ :ref:`evap_pet_ambav1_snow_daily` integration test (second response unit):
347
+
348
+ >>> ambav.sequences.logs.loggedprecipitation = [10.0]
349
+ >>> ambav.sequences.logs.loggedpotentialsoilevapotranspiration = [2.282495]
350
+ >>> model.calc_pe_pet_v1()
351
+ >>> fluxes.pe
352
+ pe(3.301949, 1.146759, 1.890672)
353
+ >>> fluxes.pet
354
+ pet(2.324763, 0.807385, 0.0)
355
+
356
+ .. testsetup::
357
+
358
+ >>> del pub.timegrids
359
+ """
360
+
361
+ DERIVEDPARAMETERS = (wland_derived.NUL,)
362
+ RESULTSEQUENCES = (wland_fluxes.PE, wland_fluxes.PET)
363
+
364
+ @staticmethod
365
+ def __call__(model: modeltools.Model, submodel: petinterfaces.PETModel_V2) -> None:
366
+ der = model.parameters.derived.fastaccess
367
+ flu = model.sequences.fluxes.fastaccess
368
+ submodel.determine_potentialinterceptionevaporation()
369
+ submodel.determine_potentialsoilevapotranspiration()
370
+ submodel.determine_potentialwaterevaporation()
371
+ for k in range(der.nul):
372
+ flu.pe[k] = submodel.get_potentialinterceptionevaporation(k)
373
+ flu.pet[k] = submodel.get_potentialsoilevapotranspiration(k)
374
+ flu.pe[der.nul] = submodel.get_potentialwaterevaporation(der.nul)
375
+ flu.pet[der.nul] = 0.0
376
+
377
+
378
+ class Calc_PE_PET_V1(modeltools.Method):
379
+ """Let a submodel that complies with the |PETModel_V1| or |PETModel_V2| interface
380
+ calculate the potential evapotranspiration of the land areas and the potential
381
+ evaporation of the surface water storage."""
382
+
383
+ SUBMODELINTERFACES = (petinterfaces.PETModel_V1, petinterfaces.PETModel_V2)
384
+ SUBMETHODS = (Calc_PE_PET_PETModel_V1, Calc_PE_PET_PETModel_V2)
385
+ DERIVEDPARAMETERS = (wland_derived.NUL,)
386
+ RESULTSEQUENCES = (wland_fluxes.PE, wland_fluxes.PET)
387
+
388
+ @staticmethod
389
+ def __call__(model: modeltools.Model) -> None:
390
+ if model.petmodel_typeid == 1:
391
+ model.calc_pe_pet_petmodel_v1(
392
+ cast(petinterfaces.PETModel_V1, model.petmodel)
393
+ )
394
+ elif model.petmodel_typeid == 2:
395
+ model.calc_pe_pet_petmodel_v2(
396
+ cast(petinterfaces.PETModel_V2, model.petmodel)
397
+ )
398
+ # ToDo:
399
+ # else:
400
+ # assert_never(model.petmodel)
401
+
402
+
403
+ class Calc_TF_V1(modeltools.Method):
404
+ r"""Calculate the total amount of throughfall of the land areas.
405
+
406
+ Basic equation (discontinuous):
407
+ .. math::
408
+ TF = \begin{cases}
409
+ P &|\ IC > IT
410
+ \\
411
+ 0 &|\ IC < IT
412
+ \end{cases}
413
+
414
+ Examples:
415
+
416
+ >>> from hydpy import pub, UnitTest
417
+ >>> pub.timegrids = '2000-03-30', '2000-04-03', '1d'
418
+ >>> from hydpy.models.wland import *
419
+ >>> parameterstep()
420
+ >>> nu(2)
421
+ >>> lt(FIELD, WATER)
422
+ >>> ih(0.2)
423
+ >>> lai.field_mar = 5.0
424
+ >>> lai.field_apr = 10.0
425
+ >>> derived.moy.update()
426
+ >>> derived.nul.update()
427
+ >>> fluxes.pc = 5.0
428
+ >>> test = UnitTest(
429
+ ... model=model,
430
+ ... method=model.calc_tf_v1,
431
+ ... last_example=6,
432
+ ... parseqs=(states.ic, fluxes.tf),
433
+ ... )
434
+ >>> test.nexts.ic = -4.0, 0.0, 1.0, 2.0, 3.0, 7.0
435
+
436
+ Without smoothing:
437
+
438
+ >>> sh(0.0)
439
+ >>> derived.rh1.update()
440
+ >>> model.idx_sim = pub.timegrids.init['2000-03-31']
441
+ >>> test()
442
+ | ex. | ic | tf |
443
+ -------------------------------
444
+ | 1 | -4.0 -4.0 | 0.0 0.0 |
445
+ | 2 | 0.0 0.0 | 0.0 0.0 |
446
+ | 3 | 1.0 1.0 | 2.5 0.0 |
447
+ | 4 | 2.0 2.0 | 5.0 0.0 |
448
+ | 5 | 3.0 3.0 | 5.0 0.0 |
449
+ | 6 | 7.0 7.0 | 5.0 0.0 |
450
+
451
+ With smoothing:
452
+
453
+ >>> sh(1.0)
454
+ >>> derived.rh1.update()
455
+ >>> model.idx_sim = pub.timegrids.init['2000-04-01']
456
+ >>> test()
457
+ | ex. | ic | tf |
458
+ -----------------------------------
459
+ | 1 | -4.0 -4.0 | 0.0 0.0 |
460
+ | 2 | 0.0 0.0 | 0.00051 0.0 |
461
+ | 3 | 1.0 1.0 | 0.05 0.0 |
462
+ | 4 | 2.0 2.0 | 2.5 0.0 |
463
+ | 5 | 3.0 3.0 | 4.95 0.0 |
464
+ | 6 | 7.0 7.0 | 5.0 0.0 |
465
+
466
+ .. testsetup::
467
+
468
+ >>> del pub.timegrids
469
+ """
470
+
471
+ CONTROLPARAMETERS = (wland_control.LT, wland_control.LAI, wland_control.IH)
472
+ DERIVEDPARAMETERS = (wland_derived.MOY, wland_derived.NUL, wland_derived.RH1)
473
+ REQUIREDSEQUENCES = (wland_fluxes.PC, wland_states.IC)
474
+ RESULTSEQUENCES = (wland_fluxes.TF,)
475
+
476
+ @staticmethod
477
+ def __call__(model: modeltools.Model) -> None:
478
+ con = model.parameters.control.fastaccess
479
+ der = model.parameters.derived.fastaccess
480
+ flu = model.sequences.fluxes.fastaccess
481
+ sta = model.sequences.states.fastaccess
482
+ for k in range(der.nul):
483
+ lai: float = con.lai[con.lt[k] - SEALED, der.moy[model.idx_sim]]
484
+ flu.tf[k] = flu.pc * smoothutils.smooth_logistic1(
485
+ sta.ic[k] - con.ih * lai, der.rh1
486
+ )
487
+ flu.tf[der.nul] = 0.0
488
+
489
+
490
+ class Calc_EI_V1(modeltools.Method):
491
+ r"""Calculate the interception evaporation of the land areas.
492
+
493
+ Basic equation (discontinuous):
494
+ .. math::
495
+ EI = \begin{cases}
496
+ PE &|\ IC > 0
497
+ \\
498
+ 0 &|\ IC < 0
499
+ \end{cases}
500
+
501
+ Examples:
502
+
503
+ >>> from hydpy.models.wland import *
504
+ >>> parameterstep()
505
+ >>> nu(2)
506
+ >>> derived.nul.update()
507
+ >>> fluxes.pe = 5.0
508
+ >>> from hydpy import UnitTest
509
+ >>> test = UnitTest(
510
+ ... model=model,
511
+ ... method=model.calc_ei_v1,
512
+ ... last_example=9,
513
+ ... parseqs=(states.ic, fluxes.ei)
514
+ ... )
515
+ >>> test.nexts.ic = -4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0
516
+
517
+ Without smoothing:
518
+
519
+ >>> sh(0.0)
520
+ >>> derived.rh1.update()
521
+ >>> test()
522
+ | ex. | ic | ei |
523
+ -------------------------------
524
+ | 1 | -4.0 -4.0 | 0.0 0.0 |
525
+ | 2 | -3.0 -3.0 | 0.0 0.0 |
526
+ | 3 | -2.0 -2.0 | 0.0 0.0 |
527
+ | 4 | -1.0 -1.0 | 0.0 0.0 |
528
+ | 5 | 0.0 0.0 | 2.5 0.0 |
529
+ | 6 | 1.0 1.0 | 5.0 0.0 |
530
+ | 7 | 2.0 2.0 | 5.0 0.0 |
531
+ | 8 | 3.0 3.0 | 5.0 0.0 |
532
+ | 9 | 4.0 4.0 | 5.0 0.0 |
533
+
534
+
535
+ With smoothing:
536
+
537
+ >>> sh(1.0)
538
+ >>> derived.rh1.update()
539
+ >>> test()
540
+ | ex. | ic | ei |
541
+ ------------------------------------
542
+ | 1 | -4.0 -4.0 | 0.0 0.0 |
543
+ | 2 | -3.0 -3.0 | 0.000005 0.0 |
544
+ | 3 | -2.0 -2.0 | 0.00051 0.0 |
545
+ | 4 | -1.0 -1.0 | 0.05 0.0 |
546
+ | 5 | 0.0 0.0 | 2.5 0.0 |
547
+ | 6 | 1.0 1.0 | 4.95 0.0 |
548
+ | 7 | 2.0 2.0 | 4.99949 0.0 |
549
+ | 8 | 3.0 3.0 | 4.999995 0.0 |
550
+ | 9 | 4.0 4.0 | 5.0 0.0 |
551
+
552
+ """
553
+
554
+ DERIVEDPARAMETERS = (wland_derived.NUL, wland_derived.RH1)
555
+ REQUIREDSEQUENCES = (wland_fluxes.PE, wland_states.IC)
556
+ RESULTSEQUENCES = (wland_fluxes.EI,)
557
+
558
+ @staticmethod
559
+ def __call__(model: modeltools.Model) -> None:
560
+ der = model.parameters.derived.fastaccess
561
+ flu = model.sequences.fluxes.fastaccess
562
+ sta = model.sequences.states.fastaccess
563
+ for k in range(der.nul):
564
+ flu.ei[k] = flu.pe[k] * (smoothutils.smooth_logistic1(sta.ic[k], der.rh1))
565
+ flu.ei[der.nul] = 0.0
566
+
567
+
568
+ class Calc_FR_V1(modeltools.Method):
569
+ r"""Determine the fraction between rainfall and total precipitation.
570
+
571
+ Basic equation:
572
+ :math:`FR = \frac{T- \left( TT - TI / 2 \right)}{TI}`
573
+
574
+ Restriction:
575
+ :math:`0 \leq FR \leq 1`
576
+
577
+ Examples:
578
+
579
+ >>> from hydpy.models.wland import *
580
+ >>> parameterstep()
581
+ >>> tt(1.0)
582
+ >>> ti(4.0)
583
+ >>> from hydpy import UnitTest
584
+ >>> test = UnitTest(
585
+ ... model=model,
586
+ ... method=model.calc_fr_v1,
587
+ ... last_example=9,
588
+ ... parseqs=(inputs.t, aides.fr)
589
+ ... )
590
+ >>> test.nexts.t = -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0
591
+ >>> test()
592
+ | ex. | t | fr |
593
+ ---------------------
594
+ | 1 | -3.0 | 0.0 |
595
+ | 2 | -2.0 | 0.0 |
596
+ | 3 | -1.0 | 0.0 |
597
+ | 4 | 0.0 | 0.25 |
598
+ | 5 | 1.0 | 0.5 |
599
+ | 6 | 2.0 | 0.75 |
600
+ | 7 | 3.0 | 1.0 |
601
+ | 8 | 4.0 | 1.0 |
602
+ | 9 | 5.0 | 1.0 |
603
+ """
604
+
605
+ CONTROLPARAMETERS = (wland_control.TT, wland_control.TI)
606
+ REQUIREDSEQUENCES = (wland_inputs.T,)
607
+ RESULTSEQUENCES = (wland_aides.FR,)
608
+
609
+ @staticmethod
610
+ def __call__(model: modeltools.Model) -> None:
611
+ con = model.parameters.control.fastaccess
612
+ inp = model.sequences.inputs.fastaccess
613
+ aid = model.sequences.aides.fastaccess
614
+ if inp.t >= (con.tt + con.ti / 2.0):
615
+ aid.fr = 1.0
616
+ elif inp.t <= (con.tt - con.ti / 2.0):
617
+ aid.fr = 0.0
618
+ else:
619
+ aid.fr = (inp.t - (con.tt - con.ti / 2.0)) / con.ti
620
+
621
+
622
+ class Calc_RF_V1(modeltools.Method):
623
+ r"""Calculate the liquid amount of throughfall (rainfall) of the land areas.
624
+
625
+ Basic equation:
626
+ :math:`RF = FR \cdot TF`
627
+
628
+ Example:
629
+
630
+ >>> from hydpy.models.wland import *
631
+ >>> parameterstep()
632
+ >>> nu(2)
633
+ >>> derived.nul.update()
634
+ >>> fluxes.tf = 2.0
635
+ >>> aides.fr = 0.8
636
+ >>> model.calc_rf_v1()
637
+ >>> fluxes.rf
638
+ rf(1.6, 0.0)
639
+ """
640
+
641
+ DERIVEDPARAMETERS = (wland_derived.NUL,)
642
+ REQUIREDSEQUENCES = (wland_fluxes.TF, wland_aides.FR)
643
+ RESULTSEQUENCES = (wland_fluxes.RF,)
644
+
645
+ @staticmethod
646
+ def __call__(model: modeltools.Model) -> None:
647
+ der = model.parameters.derived.fastaccess
648
+ flu = model.sequences.fluxes.fastaccess
649
+ aid = model.sequences.aides.fastaccess
650
+ for k in range(der.nul):
651
+ flu.rf[k] = aid.fr * flu.tf[k]
652
+ flu.rf[der.nul] = 0.0
653
+
654
+
655
+ class Calc_SF_V1(modeltools.Method):
656
+ r"""Calculate the frozen amount of throughfall (snowfall) of the land areas.
657
+
658
+ Basic equation:
659
+ :math:`SF = (1-FR) \cdot TF`
660
+
661
+ Example:
662
+
663
+ >>> from hydpy.models.wland import *
664
+ >>> parameterstep()
665
+ >>> nu(2)
666
+ >>> derived.nul.update()
667
+ >>> fluxes.tf = 2.0
668
+ >>> aides.fr = 0.8
669
+ >>> model.calc_sf_v1()
670
+ >>> fluxes.sf
671
+ sf(0.4, 0.0)
672
+ """
673
+
674
+ DERIVEDPARAMETERS = (wland_derived.NUL,)
675
+ REQUIREDSEQUENCES = (wland_fluxes.TF, wland_aides.FR)
676
+ RESULTSEQUENCES = (wland_fluxes.SF,)
677
+
678
+ @staticmethod
679
+ def __call__(model: modeltools.Model) -> None:
680
+ der = model.parameters.derived.fastaccess
681
+ flu = model.sequences.fluxes.fastaccess
682
+ aid = model.sequences.aides.fastaccess
683
+ for k in range(der.nul):
684
+ flu.sf[k] = (1.0 - aid.fr) * flu.tf[k]
685
+ flu.sf[der.nul] = 0.0
686
+
687
+
688
+ class Calc_PM_V1(modeltools.Method):
689
+ r"""Calculate the potential snowmelt of the land areas.
690
+
691
+ Basic equation (discontinous):
692
+ :math:`PM = max \left( DDF \cdot (T - DDT), 0 \right)`
693
+
694
+ Examples:
695
+
696
+ >>> from hydpy.models.wland import *
697
+ >>> simulationstep("12h")
698
+ >>> parameterstep("1d")
699
+ >>> nu(2)
700
+ >>> derived.nul.update()
701
+ >>> ddf(4.0)
702
+ >>> ddt(1.0)
703
+ >>> from hydpy import UnitTest
704
+ >>> test = UnitTest(
705
+ ... model=model,
706
+ ... method=model.calc_pm_v1,
707
+ ... last_example=11,
708
+ ... parseqs=(inputs.t, fluxes.pm)
709
+ ... )
710
+ >>> test.nexts.t = -4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0
711
+
712
+ Without smoothing:
713
+
714
+ >>> st(0.0)
715
+ >>> derived.rt2.update()
716
+ >>> test()
717
+ | ex. | t | pm |
718
+ --------------------------
719
+ | 1 | -4.0 | 0.0 0.0 |
720
+ | 2 | -3.0 | 0.0 0.0 |
721
+ | 3 | -2.0 | 0.0 0.0 |
722
+ | 4 | -1.0 | 0.0 0.0 |
723
+ | 5 | 0.0 | 0.0 0.0 |
724
+ | 6 | 1.0 | 0.0 0.0 |
725
+ | 7 | 2.0 | 2.0 0.0 |
726
+ | 8 | 3.0 | 4.0 0.0 |
727
+ | 9 | 4.0 | 6.0 0.0 |
728
+ | 10 | 5.0 | 8.0 0.0 |
729
+ | 11 | 6.0 | 10.0 0.0 |
730
+
731
+ With smoothing:
732
+
733
+ >>> st(1.0)
734
+ >>> derived.rt2.update()
735
+ >>> test()
736
+ | ex. | t | pm |
737
+ ------------------------------
738
+ | 1 | -4.0 | 0.0 0.0 |
739
+ | 2 | -3.0 | 0.000001 0.0 |
740
+ | 3 | -2.0 | 0.000024 0.0 |
741
+ | 4 | -1.0 | 0.000697 0.0 |
742
+ | 5 | 0.0 | 0.02 0.0 |
743
+ | 6 | 1.0 | 0.411048 0.0 |
744
+ | 7 | 2.0 | 2.02 0.0 |
745
+ | 8 | 3.0 | 4.000697 0.0 |
746
+ | 9 | 4.0 | 6.000024 0.0 |
747
+ | 10 | 5.0 | 8.000001 0.0 |
748
+ | 11 | 6.0 | 10.0 0.0 |
749
+ """
750
+
751
+ CONTROLPARAMETERS = (wland_control.DDF, wland_control.DDT)
752
+ DERIVEDPARAMETERS = (wland_derived.NUL, wland_derived.RT2)
753
+ REQUIREDSEQUENCES = (wland_inputs.T,)
754
+ RESULTSEQUENCES = (wland_fluxes.PM,)
755
+
756
+ @staticmethod
757
+ def __call__(model: modeltools.Model) -> None:
758
+ con = model.parameters.control.fastaccess
759
+ der = model.parameters.derived.fastaccess
760
+ inp = model.sequences.inputs.fastaccess
761
+ flu = model.sequences.fluxes.fastaccess
762
+ for k in range(der.nul):
763
+ flu.pm[k] = con.ddf[k] * smoothutils.smooth_logistic2(
764
+ inp.t - con.ddt, der.rt2
765
+ )
766
+ flu.pm[der.nul] = 0.0
767
+
768
+
769
+ class Calc_AM_V1(modeltools.Method):
770
+ r"""Calculate the actual snowmelt of the land areas.
771
+
772
+ Basic equation (discontinous):
773
+ .. math::
774
+ AM = \begin{cases}
775
+ PM &|\ SP > 0
776
+ \\
777
+ 0 &|\ SP < 0
778
+ \end{cases}
779
+
780
+ Examples:
781
+
782
+ >>> from hydpy.models.wland import *
783
+ >>> parameterstep()
784
+ >>> nu(2)
785
+ >>> derived.nul.update()
786
+ >>> fluxes.pm = 2.0
787
+ >>> from hydpy import UnitTest
788
+ >>> test = UnitTest(
789
+ ... model=model,
790
+ ... method=model.calc_am_v1,
791
+ ... last_example=9,
792
+ ... parseqs=(states.sp, fluxes.am)
793
+ ... )
794
+ >>> test.nexts.sp = -4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0
795
+
796
+ Without smoothing:
797
+
798
+ >>> sh(0.0)
799
+ >>> derived.rh1.update()
800
+ >>> test()
801
+ | ex. | sp | am |
802
+ -------------------------------
803
+ | 1 | -4.0 -4.0 | 0.0 0.0 |
804
+ | 2 | -3.0 -3.0 | 0.0 0.0 |
805
+ | 3 | -2.0 -2.0 | 0.0 0.0 |
806
+ | 4 | -1.0 -1.0 | 0.0 0.0 |
807
+ | 5 | 0.0 0.0 | 1.0 0.0 |
808
+ | 6 | 1.0 1.0 | 2.0 0.0 |
809
+ | 7 | 2.0 2.0 | 2.0 0.0 |
810
+ | 8 | 3.0 3.0 | 2.0 0.0 |
811
+ | 9 | 4.0 4.0 | 2.0 0.0 |
812
+
813
+ With smoothing:
814
+
815
+ >>> sh(1.0)
816
+ >>> derived.rh1.update()
817
+ >>> test()
818
+ | ex. | sp | am |
819
+ ------------------------------------
820
+ | 1 | -4.0 -4.0 | 0.0 0.0 |
821
+ | 2 | -3.0 -3.0 | 0.000002 0.0 |
822
+ | 3 | -2.0 -2.0 | 0.000204 0.0 |
823
+ | 4 | -1.0 -1.0 | 0.02 0.0 |
824
+ | 5 | 0.0 0.0 | 1.0 0.0 |
825
+ | 6 | 1.0 1.0 | 1.98 0.0 |
826
+ | 7 | 2.0 2.0 | 1.999796 0.0 |
827
+ | 8 | 3.0 3.0 | 1.999998 0.0 |
828
+ | 9 | 4.0 4.0 | 2.0 0.0 |
829
+
830
+ """
831
+
832
+ DERIVEDPARAMETERS = (wland_derived.NUL, wland_derived.RH1)
833
+ REQUIREDSEQUENCES = (wland_fluxes.PM, wland_states.SP)
834
+ RESULTSEQUENCES = (wland_fluxes.AM,)
835
+
836
+ @staticmethod
837
+ def __call__(model: modeltools.Model) -> None:
838
+ der = model.parameters.derived.fastaccess
839
+ flu = model.sequences.fluxes.fastaccess
840
+ sta = model.sequences.states.fastaccess
841
+ for k in range(der.nul):
842
+ flu.am[k] = flu.pm[k] * smoothutils.smooth_logistic1(sta.sp[k], der.rh1)
843
+ flu.am[der.nul] = 0.0
844
+
845
+
846
+ class Calc_PS_V1(modeltools.Method):
847
+ r"""Calculate the precipitation entering the surface water reservoir.
848
+
849
+ Basic equation:
850
+ :math:`PS = PC`
851
+
852
+ Example:
853
+
854
+ >>> from hydpy.models.wland import *
855
+ >>> parameterstep()
856
+ >>> fluxes.pc = 3.0
857
+ >>> model.calc_ps_v1()
858
+ >>> fluxes.ps
859
+ ps(3.0)
860
+ """
861
+
862
+ REQUIREDSEQUENCES = (wland_fluxes.PC,)
863
+ RESULTSEQUENCES = (wland_fluxes.PS,)
864
+
865
+ @staticmethod
866
+ def __call__(model: modeltools.Model) -> None:
867
+ flu = model.sequences.fluxes.fastaccess
868
+ flu.ps = flu.pc
869
+
870
+
871
+ class Calc_WE_W_V1(modeltools.Method):
872
+ r"""Calculate the wetness index for the elevated and the lowland regions.
873
+
874
+ Basic equation for the lowland region (the elevated region is handled analogous):
875
+ :math:`W = cos \left(
876
+ \frac{min \big( max(DV, \, 0), \, CW \big) \cdot Pi}{CW} \right)
877
+ \cdot \frac{1}{2} + \frac{1}{2}`
878
+
879
+ Examples:
880
+
881
+ >>> from hydpy.models.wland import *
882
+ >>> parameterstep()
883
+ >>> cwe(200.0)
884
+ >>> cw(400.0)
885
+
886
+ >>> derived.nuge(1)
887
+ >>> derived.nug(1)
888
+ >>> from hydpy import UnitTest
889
+ >>> test = UnitTest(
890
+ ... model=model,
891
+ ... method=model.calc_we_w_v1,
892
+ ... last_example=11,
893
+ ... parseqs=(states.dve, states.dv, aides.we, aides.w)
894
+ ... )
895
+ >>> test.nexts.dve = (
896
+ ... -50.0, -5.0, 0.0, 5.0, 50.0, 100.0, 150.0, 195.0, 200.0, 205.0, 250.0)
897
+ >>> test.nexts.dv = tuple(dv + 100.0 for dv in test.nexts.dve)
898
+ >>> test()
899
+ | ex. | dve | dv | we | w |
900
+ ---------------------------------------------
901
+ | 1 | -50.0 | 50.0 | 1.0 | 0.96194 |
902
+ | 2 | -5.0 | 95.0 | 1.0 | 0.867161 |
903
+ | 3 | 0.0 | 100.0 | 1.0 | 0.853553 |
904
+ | 4 | 5.0 | 105.0 | 0.998459 | 0.8394 |
905
+ | 5 | 50.0 | 150.0 | 0.853553 | 0.691342 |
906
+ | 6 | 100.0 | 200.0 | 0.5 | 0.5 |
907
+ | 7 | 150.0 | 250.0 | 0.146447 | 0.308658 |
908
+ | 8 | 195.0 | 295.0 | 0.001541 | 0.1606 |
909
+ | 9 | 200.0 | 300.0 | 0.0 | 0.146447 |
910
+ | 10 | 205.0 | 305.0 | 0.0 | 0.132839 |
911
+ | 11 | 250.0 | 350.0 | 0.0 | 0.03806 |
912
+
913
+ >>> derived.nuge(0)
914
+ >>> derived.nug(0)
915
+ >>> model.calc_we_w_v1()
916
+ >>> aides.we
917
+ we(nan)
918
+ >>> aides.w
919
+ w(nan)
920
+ """
921
+
922
+ CONTROLPARAMETERS = (wland_control.CWE, wland_control.CW)
923
+ DERIVEDPARAMETERS = (wland_derived.NUGE, wland_derived.NUG)
924
+ FIXEDPARAMETERS = (wland_fixed.Pi,)
925
+ REQUIREDSEQUENCES = (wland_states.DVE, wland_states.DV)
926
+ RESULTSEQUENCES = (wland_aides.WE, wland_aides.W)
927
+
928
+ @staticmethod
929
+ def __call__(model: modeltools.Model) -> None:
930
+ con = model.parameters.control.fastaccess
931
+ der = model.parameters.derived.fastaccess
932
+ fix = model.parameters.fixed.fastaccess
933
+ sta = model.sequences.states.fastaccess
934
+ aid = model.sequences.aides.fastaccess
935
+ if der.nuge:
936
+ aid.we = 0.5 + 0.5 * modelutils.cos(
937
+ min(max(sta.dve, 0.0), con.cwe) * fix.pi / con.cwe
938
+ )
939
+ else:
940
+ aid.we = modelutils.nan
941
+ if der.nug:
942
+ aid.w = 0.5 + 0.5 * modelutils.cos(
943
+ min(max(sta.dv, 0.0), con.cw) * fix.pi / con.cw
944
+ )
945
+ else:
946
+ aid.w = modelutils.nan
947
+
948
+
949
+ class Calc_PVE_PV_V1(modeltools.Method):
950
+ r"""Calculate the rainfall (and snowmelt) entering the vadose zone in the elevated
951
+ and lowland regions.
952
+
953
+ Basic equation for the lowland region (the elevated region is handled analogous):
954
+ .. math::
955
+ PV = \sum_{i=1}^{NUL} \left ( \frac{AUR_i}{AGR} \cdot (RF_i + AM_i) \cdot
956
+ \begin{cases}
957
+ 0 &|\ LT_i = SEALED
958
+ \\
959
+ 1-W &|\ LT_i \neq SEALED
960
+ \end{cases} \right )
961
+
962
+ Example:
963
+
964
+ >>> from hydpy.models.wland import *
965
+ >>> parameterstep()
966
+ >>> nu(4)
967
+ >>> derived.nul.update()
968
+ >>> lt(FIELD, SOIL, SEALED, WATER)
969
+ >>> aur(0.35, 0.1, 0.05, 0.5)
970
+ >>> fluxes.rf = 3.0, 2.0, 1.0, 0.0
971
+ >>> fluxes.am = 1.0, 2.0, 3.0, 0.0
972
+ >>> aides.we = 0.75
973
+ >>> aides.w = 0.25
974
+
975
+ >>> er(True)
976
+ >>> derived.agre.update()
977
+ >>> derived.agr.update()
978
+ >>> model.calc_pve_pv_v1()
979
+ >>> fluxes.pve
980
+ pve(1.0)
981
+ >>> fluxes.pv
982
+ pv(0.0)
983
+
984
+ >>> er(False)
985
+ >>> derived.agre.update()
986
+ >>> derived.agr.update()
987
+ >>> model.calc_pve_pv_v1()
988
+ >>> fluxes.pve
989
+ pve(0.0)
990
+ >>> fluxes.pv
991
+ pv(3.0)
992
+ """
993
+
994
+ CONTROLPARAMETERS = (wland_control.LT, wland_control.ER, wland_control.AUR)
995
+ DERIVEDPARAMETERS = (wland_derived.NUL, wland_derived.AGRE, wland_derived.AGR)
996
+ REQUIREDSEQUENCES = (
997
+ wland_fluxes.RF,
998
+ wland_fluxes.AM,
999
+ wland_aides.WE,
1000
+ wland_aides.W,
1001
+ )
1002
+ RESULTSEQUENCES = (wland_fluxes.PVE, wland_fluxes.PV)
1003
+
1004
+ @staticmethod
1005
+ def __call__(model: modeltools.Model) -> None:
1006
+ con = model.parameters.control.fastaccess
1007
+ der = model.parameters.derived.fastaccess
1008
+ flu = model.sequences.fluxes.fastaccess
1009
+ aid = model.sequences.aides.fastaccess
1010
+ flu.pve, flu.pv = 0.0, 0.0
1011
+ for k in range(der.nul):
1012
+ if con.lt[k] != SEALED:
1013
+ p: float = flu.rf[k] + flu.am[k]
1014
+ if con.er[k]:
1015
+ flu.pve += p * (1.0 - aid.we) * con.aur[k] / der.agre
1016
+ else:
1017
+ flu.pv += p * (1.0 - aid.w) * con.aur[k] / der.agr
1018
+
1019
+
1020
+ class Calc_PQ_V1(modeltools.Method):
1021
+ r"""Calculate the rainfall (and snowmelt) entering the quickflow reservoir.
1022
+
1023
+ Basic equation:
1024
+ .. math::
1025
+ PQ = \sum_{i=1}^{NUL} \frac{AUR_i}{ALR} \cdot (RF_i + AM_i) \cdot
1026
+ \begin{cases}
1027
+ 1 &|\ LT_i = SEALED
1028
+ \\
1029
+ WE &|\ LT_i \neq SEALED \ \land \ ER_i
1030
+ \\
1031
+ W &|\ LT_i \neq SEALED \ \land \ \overline{ER_i}
1032
+ \end{cases}
1033
+
1034
+ Example:
1035
+
1036
+ >>> from hydpy.models.wland import *
1037
+ >>> parameterstep()
1038
+ >>> nu(4)
1039
+ >>> lt(FIELD, SOIL, SEALED, WATER)
1040
+ >>> aur(0.3, 0.15, 0.05, 0.5)
1041
+ >>> derived.nul.update()
1042
+ >>> derived.alr.update()
1043
+ >>> fluxes.rf = 3.0, 2.0, 1.0, 0.0
1044
+ >>> fluxes.am = 1.0, 2.0, 2.0, 0.0
1045
+ >>> aides.w = 0.75
1046
+ >>> model.calc_pq_v1()
1047
+ >>> fluxes.pq
1048
+ pq(3.0)
1049
+ """
1050
+
1051
+ CONTROLPARAMETERS = (wland_control.LT, wland_control.ER, wland_control.AUR)
1052
+ DERIVEDPARAMETERS = (wland_derived.NUL, wland_derived.ALR)
1053
+ REQUIREDSEQUENCES = (
1054
+ wland_fluxes.RF,
1055
+ wland_fluxes.AM,
1056
+ wland_aides.WE,
1057
+ wland_aides.W,
1058
+ )
1059
+ RESULTSEQUENCES = (wland_fluxes.PQ,)
1060
+
1061
+ @staticmethod
1062
+ def __call__(model: modeltools.Model) -> None:
1063
+ con = model.parameters.control.fastaccess
1064
+ der = model.parameters.derived.fastaccess
1065
+ flu = model.sequences.fluxes.fastaccess
1066
+ aid = model.sequences.aides.fastaccess
1067
+ flu.pq = 0.0
1068
+ for k in range(der.nul):
1069
+ pq: float = con.aur[k] / der.alr * (flu.rf[k] + flu.am[k])
1070
+ if con.lt[k] != SEALED:
1071
+ pq *= aid.we if con.er[k] else aid.w
1072
+ flu.pq += pq
1073
+
1074
+
1075
+ class Calc_BetaE_Beta_V1(modeltools.Method):
1076
+ r"""Calculate the evapotranspiration reduction factor for the elevated and lowland
1077
+ regions.
1078
+
1079
+ Basic equation for the lowland region (the elevated region is handled analogous):
1080
+ :math:`Beta = \frac{1 - x}{1 + x} \cdot \frac{1}{2} + \frac{1}{2}`
1081
+
1082
+ :math:`x = exp \left( Zeta1 \cdot (DV - Zeta2) \right)`
1083
+
1084
+ Examples:
1085
+
1086
+ >>> from hydpy.models.wland import *
1087
+ >>> parameterstep()
1088
+ >>> zeta1(0.02)
1089
+ >>> zeta2(400.0)
1090
+
1091
+ >>> derived.nuge(1)
1092
+ >>> derived.nug(1)
1093
+ >>> from hydpy import UnitTest
1094
+ >>> test = UnitTest(
1095
+ ... model=model,
1096
+ ... method=model.calc_betae_beta_v1,
1097
+ ... last_example=12,
1098
+ ... parseqs=(states.dve, states.dv, aides.betae, aides.beta)
1099
+ ... )
1100
+ >>> test.nexts.dve = (
1101
+ ... -100.0, 0.0, 100.0, 200.0, 300.0, 400.0,
1102
+ ... 500.0, 600.0, 700.0, 800.0, 900.0, 100000.0
1103
+ ... )
1104
+ >>> test.nexts.dv = tuple(reversed(test.nexts.dve))
1105
+ >>> test()
1106
+ | ex. | dve | dv | betae | beta |
1107
+ ---------------------------------------------------
1108
+ | 1 | -100.0 | 100000.0 | 0.999955 | 0.0 |
1109
+ | 2 | 0.0 | 900.0 | 0.999665 | 0.000045 |
1110
+ | 3 | 100.0 | 800.0 | 0.997527 | 0.000335 |
1111
+ | 4 | 200.0 | 700.0 | 0.982014 | 0.002473 |
1112
+ | 5 | 300.0 | 600.0 | 0.880797 | 0.017986 |
1113
+ | 6 | 400.0 | 500.0 | 0.5 | 0.119203 |
1114
+ | 7 | 500.0 | 400.0 | 0.119203 | 0.5 |
1115
+ | 8 | 600.0 | 300.0 | 0.017986 | 0.880797 |
1116
+ | 9 | 700.0 | 200.0 | 0.002473 | 0.982014 |
1117
+ | 10 | 800.0 | 100.0 | 0.000335 | 0.997527 |
1118
+ | 11 | 900.0 | 0.0 | 0.000045 | 0.999665 |
1119
+ | 12 | 100000.0 | -100.0 | 0.0 | 0.999955 |
1120
+
1121
+ >>> derived.nuge(0)
1122
+ >>> derived.nug(0)
1123
+ >>> model.calc_betae_beta_v1()
1124
+ >>> aides.betae
1125
+ betae(nan)
1126
+ >>> aides.beta
1127
+ beta(nan)
1128
+ """
1129
+
1130
+ CONTROLPARAMETERS = (wland_control.Zeta1, wland_control.Zeta2)
1131
+ DERIVEDPARAMETERS = (wland_derived.NUGE, wland_derived.NUG)
1132
+ REQUIREDSEQUENCES = (wland_states.DVE, wland_states.DV)
1133
+ RESULTSEQUENCES = (wland_aides.BetaE, wland_aides.Beta)
1134
+
1135
+ @staticmethod
1136
+ def __call__(model: modeltools.Model) -> None:
1137
+ con = model.parameters.control.fastaccess
1138
+ der = model.parameters.derived.fastaccess
1139
+ sta = model.sequences.states.fastaccess
1140
+ aid = model.sequences.aides.fastaccess
1141
+
1142
+ if der.nuge:
1143
+ temp: float = con.zeta1 * (sta.dve - con.zeta2)
1144
+ if temp > 700.0:
1145
+ aid.betae = 0.0
1146
+ else:
1147
+ temp = modelutils.exp(temp)
1148
+ aid.betae = 0.5 + 0.5 * (1.0 - temp) / (1.0 + temp)
1149
+ else:
1150
+ aid.betae = modelutils.nan
1151
+
1152
+ if der.nug:
1153
+ temp = con.zeta1 * (sta.dv - con.zeta2)
1154
+ if temp > 700.0:
1155
+ aid.beta = 0.0
1156
+ else:
1157
+ temp = modelutils.exp(temp)
1158
+ aid.beta = 0.5 + 0.5 * (1.0 - temp) / (1.0 + temp)
1159
+ else:
1160
+ aid.beta = modelutils.nan
1161
+
1162
+
1163
+ class Calc_ETVE_ETV_V1(modeltools.Method):
1164
+ r"""Calculate the actual evapotranspiration from the elevated and lowland regions'
1165
+ vadose zone.
1166
+
1167
+ The following equation uses the :cite:t:`ref-Wigmosta1994` approach to extend the
1168
+ original WALRUS equation to cope with different potential values for |PE| and |PET|.
1169
+ (See the documentation on method |evap_model.Update_SoilEvapotranspiration_V3|,
1170
+ which covers the corner cases of this approach in more detail.)
1171
+
1172
+ Basic equation for the lowland region (the elevated region is handled analogous):
1173
+ .. math::
1174
+ ETV = \sum_{i=1}^{NUL} \frac{AUR_i}{AGR} \cdot
1175
+ \frac{PE_i - EI_i}{PE_i} \cdot PET_i \cdot
1176
+ \begin{cases}
1177
+ 0 &|\ LT_i = SEALED
1178
+ \\
1179
+ Beta &|\ LT_i \neq SEALED
1180
+ \end{cases}
1181
+
1182
+ Example:
1183
+
1184
+ >>> from hydpy.models.wland import *
1185
+ >>> parameterstep()
1186
+ >>> nu(4)
1187
+ >>> lt(FIELD, SOIL, SEALED, WATER)
1188
+ >>> aur(0.2, 0.2, 0.1, 0.5)
1189
+ >>> fluxes.pe = 5.0
1190
+ >>> fluxes.pet = 4.0
1191
+ >>> fluxes.ei = 1.0, 3.0, 2.0, 0.0
1192
+ >>> aides.betae = 0.75
1193
+ >>> aides.beta = 0.25
1194
+ >>> derived.nul.update()
1195
+
1196
+ >>> er(True)
1197
+ >>> derived.agr.update()
1198
+ >>> derived.agre.update()
1199
+ >>> model.calc_etve_etv_v1()
1200
+ >>> fluxes.etve
1201
+ etve(1.8)
1202
+
1203
+ >>> er(False)
1204
+ >>> derived.agr.update()
1205
+ >>> derived.agre.update()
1206
+ >>> model.calc_etve_etv_v1()
1207
+ >>> fluxes.etv
1208
+ etv(0.6)
1209
+ """
1210
+
1211
+ CONTROLPARAMETERS = (wland_control.LT, wland_control.ER, wland_control.AUR)
1212
+ DERIVEDPARAMETERS = (wland_derived.NUL, wland_derived.AGRE, wland_derived.AGR)
1213
+ REQUIREDSEQUENCES = (
1214
+ wland_fluxes.PE,
1215
+ wland_fluxes.PET,
1216
+ wland_fluxes.EI,
1217
+ wland_aides.BetaE,
1218
+ wland_aides.Beta,
1219
+ )
1220
+ RESULTSEQUENCES = (wland_fluxes.ETVE, wland_fluxes.ETV)
1221
+
1222
+ @staticmethod
1223
+ def __call__(model: modeltools.Model) -> None:
1224
+ con = model.parameters.control.fastaccess
1225
+ der = model.parameters.derived.fastaccess
1226
+ flu = model.sequences.fluxes.fastaccess
1227
+ aid = model.sequences.aides.fastaccess
1228
+ flu.etve, flu.etv = 0.0, 0.0
1229
+ for k in range(der.nul):
1230
+ if (con.lt[k] != SEALED) and (flu.pe[k] > 0.0):
1231
+ pet: float = (flu.pe[k] - flu.ei[k]) / flu.pe[k] * flu.pet[k]
1232
+ if con.er[k]:
1233
+ flu.etve += con.aur[k] / der.agre * pet * aid.betae
1234
+ else:
1235
+ flu.etv += con.aur[k] / der.agr * pet * aid.beta
1236
+
1237
+
1238
+ class Calc_ES_V1(modeltools.Method):
1239
+ r"""Calculate the actual evaporation from the surface water reservoir.
1240
+
1241
+ Basic equation (discontinous):
1242
+ .. math::
1243
+ ES = \begin{cases}
1244
+ PE &|\ HS > 0
1245
+ \\
1246
+ 0 &|\ HS \leq 0
1247
+ \end{cases}
1248
+
1249
+ Examples:
1250
+
1251
+ >>> from hydpy.models.wland import *
1252
+ >>> parameterstep()
1253
+ >>> nu(2)
1254
+ >>> derived.nul.update()
1255
+ >>> fluxes.pe = 3.0, 5.0
1256
+ >>> from hydpy import UnitTest
1257
+ >>> test = UnitTest(
1258
+ ... model=model,
1259
+ ... method=model.calc_es_v1,
1260
+ ... last_example=9,
1261
+ ... parseqs=(states.hs, fluxes.es)
1262
+ ... )
1263
+ >>> test.nexts.hs = -4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0
1264
+
1265
+ Without smoothing:
1266
+
1267
+ >>> sh(0.0)
1268
+ >>> derived.rh1.update()
1269
+ >>> test()
1270
+ | ex. | hs | es |
1271
+ --------------------
1272
+ | 1 | -4.0 | 0.0 |
1273
+ | 2 | -3.0 | 0.0 |
1274
+ | 3 | -2.0 | 0.0 |
1275
+ | 4 | -1.0 | 0.0 |
1276
+ | 5 | 0.0 | 2.5 |
1277
+ | 6 | 1.0 | 5.0 |
1278
+ | 7 | 2.0 | 5.0 |
1279
+ | 8 | 3.0 | 5.0 |
1280
+ | 9 | 4.0 | 5.0 |
1281
+
1282
+ With smoothing:
1283
+
1284
+ >>> sh(1.0)
1285
+ >>> derived.rh1.update()
1286
+ >>> test()
1287
+ | ex. | hs | es |
1288
+ -------------------------
1289
+ | 1 | -4.0 | 0.0 |
1290
+ | 2 | -3.0 | 0.000005 |
1291
+ | 3 | -2.0 | 0.00051 |
1292
+ | 4 | -1.0 | 0.05 |
1293
+ | 5 | 0.0 | 2.5 |
1294
+ | 6 | 1.0 | 4.95 |
1295
+ | 7 | 2.0 | 4.99949 |
1296
+ | 8 | 3.0 | 4.999995 |
1297
+ | 9 | 4.0 | 5.0 |
1298
+ """
1299
+
1300
+ DERIVEDPARAMETERS = (wland_derived.NUL, wland_derived.RH1)
1301
+ REQUIREDSEQUENCES = (wland_fluxes.PE, wland_states.HS)
1302
+ RESULTSEQUENCES = (wland_fluxes.ES,)
1303
+
1304
+ @staticmethod
1305
+ def __call__(model: modeltools.Model) -> None:
1306
+ der = model.parameters.derived.fastaccess
1307
+ flu = model.sequences.fluxes.fastaccess
1308
+ sta = model.sequences.states.fastaccess
1309
+ flu.es = flu.pe[der.nul] * smoothutils.smooth_logistic1(sta.hs, der.rh1)
1310
+
1311
+
1312
+ class Calc_ET_V1(modeltools.Method):
1313
+ r"""Calculate the total actual evapotranspiration.
1314
+
1315
+ Basic equation:
1316
+ :math:`ET = ASR \cdot ES + AGRE \cdot ETV\!E + AGR \cdot ETV +
1317
+ \sum_{i=1}^{NUL} AUR_i \cdot EI_i`
1318
+
1319
+ Example:
1320
+
1321
+ >>> from hydpy.models.wland import *
1322
+ >>> parameterstep()
1323
+ >>> nu(3)
1324
+ >>> lt(FIELD, SEALED, WATER)
1325
+ >>> aur(0.5, 0.3, 0.2)
1326
+ >>> er(False)
1327
+ >>> derived.nul.update()
1328
+ >>> derived.asr.update()
1329
+ >>> derived.agr.update()
1330
+ >>> derived.agre.update()
1331
+ >>> fluxes.ei = 1.0, 2.0, 0.0
1332
+ >>> fluxes.etv = 3.0
1333
+ >>> fluxes.etve = 5.0
1334
+ >>> fluxes.es = 4.0
1335
+ >>> model.calc_et_v1()
1336
+ >>> fluxes.et
1337
+ et(3.4)
1338
+ """
1339
+
1340
+ CONTROLPARAMETERS = (wland_control.AUR,)
1341
+ DERIVEDPARAMETERS = (
1342
+ wland_derived.NUL,
1343
+ wland_derived.ASR,
1344
+ wland_derived.AGRE,
1345
+ wland_derived.AGR,
1346
+ )
1347
+ REQUIREDSEQUENCES = (
1348
+ wland_fluxes.EI,
1349
+ wland_fluxes.ETVE,
1350
+ wland_fluxes.ETV,
1351
+ wland_fluxes.ES,
1352
+ )
1353
+ RESULTSEQUENCES = (wland_fluxes.ET,)
1354
+
1355
+ @staticmethod
1356
+ def __call__(model: modeltools.Model) -> None:
1357
+ con = model.parameters.control.fastaccess
1358
+ der = model.parameters.derived.fastaccess
1359
+ flu = model.sequences.fluxes.fastaccess
1360
+ ei: float = 0.0
1361
+ for k in range(der.nul):
1362
+ ei += con.aur[k] * flu.ei[k]
1363
+ flu.et = ei + der.agre * flu.etve + der.agr * flu.etv + der.asr * flu.es
1364
+
1365
+
1366
+ class Calc_DVEq_V1(modeltools.Method):
1367
+ r"""Calculate the equilibrium storage deficit of the vadose zone.
1368
+
1369
+ Basic equation (discontinuous):
1370
+ .. math::
1371
+ DV\!Eq = \begin{cases}
1372
+ 0 &|\ DG \leq PsiAE
1373
+ \\
1374
+ ThetaS \cdot \left( DG - \frac{DG^{1-1/b}}{(1-1/b) \cdot PsiAE^{-1/B}} -
1375
+ \frac{PsiAE}{1-B} \right) &|\ PsiAE < DG
1376
+ \end{cases}
1377
+
1378
+ Examples:
1379
+
1380
+ >>> from hydpy.models.wland import *
1381
+ >>> parameterstep()
1382
+ >>> thetas(0.4)
1383
+ >>> psiae(300.0)
1384
+ >>> b(5.0)
1385
+ >>> from hydpy import UnitTest
1386
+ >>> test = UnitTest(
1387
+ ... model=model,
1388
+ ... method=model.calc_dveq_v1,
1389
+ ... last_example=6,
1390
+ ... parseqs=(states.dg, aides.dveq)
1391
+ ... )
1392
+ >>> test.nexts.dg = 200.0, 300.0, 400.0, 800.0, 1600.0, 3200.0
1393
+
1394
+ Without smoothing:
1395
+
1396
+ >>> test()
1397
+ | ex. | dg | dveq |
1398
+ -----------------------------
1399
+ | 1 | 200.0 | 0.0 |
1400
+ | 2 | 300.0 | 0.0 |
1401
+ | 3 | 400.0 | 1.182498 |
1402
+ | 4 | 800.0 | 21.249634 |
1403
+ | 5 | 1600.0 | 97.612368 |
1404
+ | 6 | 3200.0 | 313.415248 |
1405
+ """
1406
+
1407
+ CONTROLPARAMETERS = (wland_control.ThetaS, wland_control.PsiAE, wland_control.B)
1408
+ DERIVEDPARAMETERS = (wland_derived.NUG,)
1409
+ REQUIREDSEQUENCES = (wland_states.DG,)
1410
+ RESULTSEQUENCES = (wland_aides.DVEq,)
1411
+
1412
+ @staticmethod
1413
+ def __call__(model: modeltools.Model) -> None:
1414
+ con = model.parameters.control.fastaccess
1415
+ der = model.parameters.derived.fastaccess
1416
+ sta = model.sequences.states.fastaccess
1417
+ aid = model.sequences.aides.fastaccess
1418
+ if der.nug:
1419
+ if sta.dg < con.psiae:
1420
+ aid.dveq = 0.0
1421
+ else:
1422
+ aid.dveq = con.thetas * (
1423
+ sta.dg
1424
+ - sta.dg ** (1.0 - 1.0 / con.b)
1425
+ / (1.0 - 1.0 / con.b)
1426
+ / con.psiae ** (-1.0 / con.b)
1427
+ - con.psiae / (1.0 - con.b)
1428
+ )
1429
+ else:
1430
+ aid.dveq = modelutils.nan
1431
+
1432
+
1433
+ class Return_DVH_V1(modeltools.Method):
1434
+ r"""Return the storage deficit of the vadose zone at a specific height above
1435
+ the groundwater table.
1436
+
1437
+ Basic equation (discontinous):
1438
+ .. math::
1439
+ DVH = \begin{cases}
1440
+ 0 &|\ DG \leq PsiAE
1441
+ \\
1442
+ ThetaS \cdot \left(1 - \left( \frac{h}{PsiAE} \right)^{-1/b} \right)
1443
+ &|\ PsiAE < DG
1444
+ \end{cases}
1445
+
1446
+ This power law is the differential of the equation underlying method
1447
+ |Calc_DVEq_V1| with respect to height. :cite:t:`ref-Brauer2014` also cites it
1448
+ (equation 6) but does not use it directly.
1449
+
1450
+ Examples:
1451
+
1452
+ >>> from hydpy.models.wland import *
1453
+ >>> parameterstep()
1454
+ >>> thetas(0.4)
1455
+ >>> psiae(300.0)
1456
+ >>> b(5.0)
1457
+
1458
+ With smoothing:
1459
+
1460
+ >>> from hydpy import repr_
1461
+ >>> sh(0.0)
1462
+ >>> derived.rh1.update()
1463
+ >>> for h in [200.0, 299.0, 300.0, 301.0, 400.0, 500.0, 600.0]:
1464
+ ... print(repr_(h), repr_(model.return_dvh_v1(h)))
1465
+ 200.0 0.0
1466
+ 299.0 0.0
1467
+ 300.0 0.0
1468
+ 301.0 0.000266
1469
+ 400.0 0.022365
1470
+ 500.0 0.038848
1471
+ 600.0 0.05178
1472
+
1473
+ Without smoothing:
1474
+
1475
+ >>> sh(1.0)
1476
+ >>> derived.rh1.update()
1477
+ >>> for h in [200.0, 299.0, 300.0, 301.0, 400.0, 500.0, 600.0]:
1478
+ ... print(repr_(h), repr_(model.return_dvh_v1(h)))
1479
+ 200.0 0.0
1480
+ 299.0 0.000001
1481
+ 300.0 0.00004
1482
+ 301.0 0.000267
1483
+ 400.0 0.022365
1484
+ 500.0 0.038848
1485
+ 600.0 0.05178
1486
+ """
1487
+
1488
+ CONTROLPARAMETERS = (wland_control.ThetaS, wland_control.PsiAE, wland_control.B)
1489
+ DERIVEDPARAMETERS = (wland_derived.RH1,)
1490
+
1491
+ @staticmethod
1492
+ def __call__(model: modeltools.Model, h: float) -> float:
1493
+ con = model.parameters.control.fastaccess
1494
+ der = model.parameters.derived.fastaccess
1495
+ h = smoothutils.smooth_max1(h, con.psiae, der.rh1)
1496
+ return con.thetas * (1.0 - (h / con.psiae) ** (-1.0 / con.b))
1497
+
1498
+
1499
+ class Calc_DVEq_V2(modeltools.Method):
1500
+ r"""Calculate the equilibrium storage deficit of the vadose zone.
1501
+
1502
+ Basic equation:
1503
+ :math:`DHEq = \int_{0}^{DG} Return\_DVH\_V1(h) \ \ dh`
1504
+
1505
+ Method |Calc_DVEq_V2| integrates |Return_DVH_V1| numerically, based on the
1506
+ Lobatto-Gauß quadrature. Hence, it should give nearly identical results as
1507
+ method |Calc_DVEq_V1|, which provides the analytical solution to the underlying
1508
+ power law. The benefit of method |Calc_DVEq_V2| is that it supports the
1509
+ regularisation of |Return_DVH_V1|, which |Calc_DVEq_V1| does not. In our
1510
+ experience, this benefit does not justify the additional numerical cost.
1511
+ However, we keep it for educational purposes, mainly as a starting point to
1512
+ implement alternative relationships between the soil water deficit and the
1513
+ groundwater table that we cannot solve analytically.
1514
+
1515
+ Examples:
1516
+
1517
+ >>> from hydpy.models.wland import *
1518
+ >>> parameterstep()
1519
+ >>> derived.nug(0)
1520
+ >>> model.calc_dveq_v2()
1521
+ >>> aides.dveq
1522
+ dveq(nan)
1523
+
1524
+ >>> derived.nug(1)
1525
+ >>> thetas(0.4)
1526
+ >>> psiae(300.0)
1527
+ >>> b(5.0)
1528
+ >>> from hydpy import UnitTest
1529
+ >>> test = UnitTest(
1530
+ ... model=model,
1531
+ ... method=model.calc_dveq_v2,
1532
+ ... last_example=8,
1533
+ ... parseqs=(states.dg, aides.dveq)
1534
+ ... )
1535
+ >>> test.nexts.dg = 200.0, 299.0, 300.0, 301.0, 400.0, 800.0, 1600.0, 3200.0
1536
+
1537
+ Without smoothing:
1538
+
1539
+ >>> sh(0.0)
1540
+ >>> derived.rh1.update()
1541
+ >>> test()
1542
+ | ex. | dg | dveq |
1543
+ -----------------------------
1544
+ | 1 | 200.0 | 0.0 |
1545
+ | 2 | 299.0 | 0.0 |
1546
+ | 3 | 300.0 | 0.0 |
1547
+ | 4 | 301.0 | 0.000133 |
1548
+ | 5 | 400.0 | 1.182498 |
1549
+ | 6 | 800.0 | 21.249634 |
1550
+ | 7 | 1600.0 | 97.612368 |
1551
+ | 8 | 3200.0 | 313.415248 |
1552
+
1553
+ With smoothing:
1554
+
1555
+ >>> sh(1.0)
1556
+ >>> derived.rh1.update()
1557
+ >>> test()
1558
+ | ex. | dg | dveq |
1559
+ -----------------------------
1560
+ | 1 | 200.0 | 0.0 |
1561
+ | 2 | 299.0 | 0.0 |
1562
+ | 3 | 300.0 | 0.000033 |
1563
+ | 4 | 301.0 | 0.000176 |
1564
+ | 5 | 400.0 | 1.182542 |
1565
+ | 6 | 800.0 | 21.24972 |
1566
+ | 7 | 1600.0 | 97.612538 |
1567
+ | 8 | 3200.0 | 313.415588 |
1568
+ """
1569
+
1570
+ CONTROLPARAMETERS = (
1571
+ wland_control.ThetaS,
1572
+ wland_control.PsiAE,
1573
+ wland_control.B,
1574
+ wland_control.SH,
1575
+ )
1576
+ DERIVEDPARAMETERS = (wland_derived.NUG, wland_derived.RH1)
1577
+ REQUIREDSEQUENCES = (wland_states.DG,)
1578
+ RESULTSEQUENCES = (wland_aides.DVEq,)
1579
+ SUBMETHODS = (Return_DVH_V1,)
1580
+
1581
+ @staticmethod
1582
+ def __call__(model: modeltools.Model) -> None:
1583
+ con = model.parameters.control.fastaccess
1584
+ der = model.parameters.derived.fastaccess
1585
+ sta = model.sequences.states.fastaccess
1586
+ aid = model.sequences.aides.fastaccess
1587
+ if der.nug:
1588
+ x0: float = -10.0 * con.sh
1589
+ if sta.dg > con.psiae:
1590
+ t1: float = model.quaddveq_v1.integrate(x0, con.psiae, 2, 20, 1e-8)
1591
+ t2: float = model.quaddveq_v1.integrate(con.psiae, sta.dg, 2, 20, 1e-8)
1592
+ aid.dveq = t1 + t2
1593
+ else:
1594
+ aid.dveq = model.quaddveq_v1.integrate(x0, sta.dg, 2, 20, 1e-8)
1595
+ else:
1596
+ aid.dveq = modelutils.nan
1597
+
1598
+
1599
+ class Calc_DVEq_V3(modeltools.Method):
1600
+ r"""Calculate the equilibrium storage deficit of the vadose zone.
1601
+
1602
+ Basic equation (discontinuous):
1603
+ .. math::
1604
+ DHEq = ThetaR \cdot DG + \begin{cases}
1605
+ 0 &|\ DG \leq PsiAE
1606
+ \\
1607
+ ThetaS \cdot \left( DG - \frac{DG^{1-1/b}}{(1-1/b) \cdot PsiAE^{-1/B}} -
1608
+ \frac{PsiAE}{1-B} \right) &|\ PsiAE < DG
1609
+ \end{cases}
1610
+
1611
+ Method |Calc_DVEq_V3| extends the original `WALRUS`_ relationship between the
1612
+ groundwater depth and the equilibrium water deficit of the vadose zone defined
1613
+ by equation 5 of :cite:t:`ref-Brauer2014` and implemented into application model
1614
+ |wland| by method |Calc_DVEq_V1|. Parameter |ThetaR| introduces a (small)
1615
+ amount of water to fill the tension-saturated area directly above the groundwater
1616
+ table. This "residual saturation" allows the direct injection of water into
1617
+ groundwater without risking infinitely fast groundwater depth changes.
1618
+
1619
+ Examples:
1620
+
1621
+ >>> from hydpy.models.wland import *
1622
+ >>> parameterstep()
1623
+ >>> thetas(0.4)
1624
+ >>> thetar(0.01)
1625
+ >>> psiae(300.0)
1626
+ >>> b(5.0)
1627
+ >>> from hydpy import UnitTest
1628
+ >>> test = UnitTest(
1629
+ ... model=model,
1630
+ ... method=model.calc_dveq_v3,
1631
+ ... last_example=8,
1632
+ ... parseqs=(states.dg, aides.dveq)
1633
+ ... )
1634
+ >>> test.nexts.dg = 200.0, 299.0, 300.0, 301.0, 400.0, 800.0, 1600.0, 3200.0
1635
+
1636
+ Without smoothing:
1637
+
1638
+ >>> test()
1639
+ | ex. | dg | dveq |
1640
+ -----------------------------
1641
+ | 1 | 200.0 | 2.0 |
1642
+ | 2 | 299.0 | 2.99 |
1643
+ | 3 | 300.0 | 3.0 |
1644
+ | 4 | 301.0 | 3.01013 |
1645
+ | 5 | 400.0 | 5.152935 |
1646
+ | 6 | 800.0 | 28.718393 |
1647
+ | 7 | 1600.0 | 111.172058 |
1648
+ | 8 | 3200.0 | 337.579867 |
1649
+ """
1650
+
1651
+ CONTROLPARAMETERS = (
1652
+ wland_control.ThetaS,
1653
+ wland_control.ThetaR,
1654
+ wland_control.PsiAE,
1655
+ wland_control.B,
1656
+ )
1657
+ DERIVEDPARAMETERS = (wland_derived.NUG,)
1658
+ REQUIREDSEQUENCES = (wland_states.DG,)
1659
+ RESULTSEQUENCES = (wland_aides.DVEq,)
1660
+
1661
+ @staticmethod
1662
+ def __call__(model: modeltools.Model) -> None:
1663
+ con = model.parameters.control.fastaccess
1664
+ der = model.parameters.derived.fastaccess
1665
+ sta = model.sequences.states.fastaccess
1666
+ aid = model.sequences.aides.fastaccess
1667
+ if der.nug:
1668
+ if sta.dg < con.psiae:
1669
+ aid.dveq = con.thetar * sta.dg
1670
+ else:
1671
+ aid.dveq = (con.thetas - con.thetar) * (
1672
+ sta.dg
1673
+ - sta.dg ** (1.0 - 1.0 / con.b)
1674
+ / (1.0 - 1.0 / con.b)
1675
+ / con.psiae ** (-1.0 / con.b)
1676
+ - con.psiae / (1.0 - con.b)
1677
+ ) + con.thetar * sta.dg
1678
+ else:
1679
+ aid.dveq = modelutils.nan
1680
+
1681
+
1682
+ class Return_DVH_V2(modeltools.Method):
1683
+ r"""Return the storage deficit of the vadose zone at a specific height above
1684
+ the groundwater table.
1685
+
1686
+ Basic equation (discontinous):
1687
+ .. math::
1688
+ DVH = ThetaR + \begin{cases}
1689
+ 0 &|\ DG \leq PsiAE
1690
+ \\
1691
+ (ThetaS-ThetaR) \cdot \left(1 - \left( \frac{h}{PsiAE} \right)^{-1/b} \right)
1692
+ &|\ PsiAE < DG
1693
+ \end{cases}
1694
+
1695
+ The given equation is the differential of the equation underlying method
1696
+ |Calc_DVEq_V3| with respect to height.
1697
+
1698
+ Examples:
1699
+
1700
+ >>> from hydpy.models.wland import *
1701
+ >>> parameterstep()
1702
+ >>> thetas(0.4)
1703
+ >>> thetar(0.01)
1704
+ >>> psiae(300.0)
1705
+ >>> b(5.0)
1706
+
1707
+ With smoothing:
1708
+
1709
+ >>> from hydpy import repr_
1710
+ >>> sh(0.0)
1711
+ >>> derived.rh1.update()
1712
+ >>> for h in [200.0, 299.0, 300.0, 301.0, 400.0, 500.0, 600.0]:
1713
+ ... print(repr_(h), repr_(model.return_dvh_v2(h)))
1714
+ 200.0 0.01
1715
+ 299.0 0.01
1716
+ 300.0 0.01
1717
+ 301.0 0.010259
1718
+ 400.0 0.031806
1719
+ 500.0 0.047877
1720
+ 600.0 0.060485
1721
+
1722
+ Without smoothing:
1723
+
1724
+ >>> sh(1.0)
1725
+ >>> derived.rh1.update()
1726
+ >>> for h in [200.0, 299.0, 300.0, 301.0, 400.0, 500.0, 600.0]:
1727
+ ... print(repr_(h), repr_(model.return_dvh_v2(h)))
1728
+ 200.0 0.01
1729
+ 299.0 0.010001
1730
+ 300.0 0.010039
1731
+ 301.0 0.01026
1732
+ 400.0 0.031806
1733
+ 500.0 0.047877
1734
+ 600.0 0.060485
1735
+ """
1736
+
1737
+ CONTROLPARAMETERS = (
1738
+ wland_control.ThetaS,
1739
+ wland_control.ThetaR,
1740
+ wland_control.PsiAE,
1741
+ wland_control.B,
1742
+ )
1743
+ DERIVEDPARAMETERS = (wland_derived.RH1,)
1744
+
1745
+ @staticmethod
1746
+ def __call__(model: modeltools.Model, h: float) -> float:
1747
+ con = model.parameters.control.fastaccess
1748
+ der = model.parameters.derived.fastaccess
1749
+ h = smoothutils.smooth_max1(h, con.psiae, der.rh1)
1750
+ return con.thetar + (
1751
+ (con.thetas - con.thetar) * (1.0 - (h / con.psiae) ** (-1.0 / con.b))
1752
+ )
1753
+
1754
+
1755
+ class Calc_DVEq_V4(modeltools.Method):
1756
+ r"""Calculate the equilibrium storage deficit of the vadose zone.
1757
+
1758
+ Basic equation:
1759
+ :math:`DHEq = \int_{0}^{DG} Return\_DVH\_V2(h) \ \ dh`
1760
+
1761
+ Method |Calc_DVEq_V4| integrates |Return_DVH_V2| numerically based on the
1762
+ Lobatto-Gauß quadrature. The short discussion in the documentation on
1763
+ |Calc_DVEq_V2| (which integrates |Return_DVH_V1|) also applies to |Calc_DVEq_V4|.
1764
+
1765
+ Examples:
1766
+
1767
+ >>> from hydpy.models.wland import *
1768
+ >>> parameterstep()
1769
+ >>> derived.nug(0)
1770
+ >>> model.calc_dveq_v4()
1771
+ >>> aides.dveq
1772
+ dveq(nan)
1773
+
1774
+ >>> derived.nug(1)
1775
+ >>> thetas(0.4)
1776
+ >>> thetar(0.01)
1777
+ >>> psiae(300.0)
1778
+ >>> b(5.0)
1779
+ >>> from hydpy import UnitTest
1780
+ >>> test = UnitTest(
1781
+ ... model=model,
1782
+ ... method=model.calc_dveq_v4,
1783
+ ... last_example=8,
1784
+ ... parseqs=(states.dg, aides.dveq)
1785
+ ... )
1786
+ >>> test.nexts.dg = 200.0, 299.0, 300.0, 301.0, 400.0, 800.0, 1600.0, 3200.0
1787
+
1788
+ Without smoothing:
1789
+
1790
+ >>> sh(0.0)
1791
+ >>> derived.rh1.update()
1792
+ >>> test()
1793
+ | ex. | dg | dveq |
1794
+ -----------------------------
1795
+ | 1 | 200.0 | 2.0 |
1796
+ | 2 | 299.0 | 2.99 |
1797
+ | 3 | 300.0 | 3.0 |
1798
+ | 4 | 301.0 | 3.01013 |
1799
+ | 5 | 400.0 | 5.152935 |
1800
+ | 6 | 800.0 | 28.718393 |
1801
+ | 7 | 1600.0 | 111.172058 |
1802
+ | 8 | 3200.0 | 337.579867 |
1803
+
1804
+ With smoothing:
1805
+
1806
+ >>> sh(1.0)
1807
+ >>> derived.rh1.update()
1808
+ >>> test()
1809
+ | ex. | dg | dveq |
1810
+ -----------------------------
1811
+ | 1 | 200.0 | 2.1 |
1812
+ | 2 | 299.0 | 3.09 |
1813
+ | 3 | 300.0 | 3.100032 |
1814
+ | 4 | 301.0 | 3.110172 |
1815
+ | 5 | 400.0 | 5.252979 |
1816
+ | 6 | 800.0 | 28.818477 |
1817
+ | 7 | 1600.0 | 111.272224 |
1818
+ | 8 | 3200.0 | 337.680198 |
1819
+ """
1820
+
1821
+ CONTROLPARAMETERS = (
1822
+ wland_control.ThetaS,
1823
+ wland_control.ThetaR,
1824
+ wland_control.PsiAE,
1825
+ wland_control.B,
1826
+ wland_control.SH,
1827
+ )
1828
+ DERIVEDPARAMETERS = (wland_derived.NUG, wland_derived.RH1)
1829
+ REQUIREDSEQUENCES = (wland_states.DG,)
1830
+ RESULTSEQUENCES = (wland_aides.DVEq,)
1831
+ SUBMETHODS = (Return_DVH_V2,)
1832
+
1833
+ @staticmethod
1834
+ def __call__(model: modeltools.Model) -> None:
1835
+ con = model.parameters.control.fastaccess
1836
+ der = model.parameters.derived.fastaccess
1837
+ sta = model.sequences.states.fastaccess
1838
+ aid = model.sequences.aides.fastaccess
1839
+ if der.nug:
1840
+ x0: float = -10.0 * con.sh
1841
+ if sta.dg > con.psiae:
1842
+ t1: float = model.quaddveq_v2.integrate(x0, con.psiae, 2, 20, 1e-8)
1843
+ t2: float = model.quaddveq_v2.integrate(con.psiae, sta.dg, 2, 20, 1e-8)
1844
+ aid.dveq = t1 + t2
1845
+ else:
1846
+ aid.dveq = model.quaddveq_v2.integrate(x0, sta.dg, 2, 20, 1e-8)
1847
+ else:
1848
+ aid.dveq = modelutils.nan
1849
+
1850
+
1851
+ class Return_ErrorDV_V1(modeltools.Method):
1852
+ r"""Calculate the difference between the equilibrium and the actual storage
1853
+ deficit of the vadose zone.
1854
+
1855
+ Basic equation:
1856
+ :math:`DV\!Eq_{Calc\_DV\!Eq\_V3} - DV`
1857
+
1858
+ Method |Return_ErrorDV_V1| uses |Calc_DVEq_V3| to calculate the equilibrium
1859
+ deficit corresponding to the current groundwater depth. The following example
1860
+ shows that it resets the values |DG| and |DVEq|, which it needs to change
1861
+ temporarily, to their original states.
1862
+
1863
+ Example:
1864
+
1865
+ >>> from hydpy.models.wland import *
1866
+ >>> parameterstep()
1867
+ >>> thetas(0.4)
1868
+ >>> thetar(0.01)
1869
+ >>> psiae(300.0)
1870
+ >>> b(5.0)
1871
+ >>> states.dg = -9.0
1872
+ >>> aides.dveq = -99.0
1873
+ >>> states.dv = 3.152935
1874
+ >>> from hydpy import round_
1875
+ >>> round_(model.return_errordv_v1(400.0))
1876
+ 2.0
1877
+ >>> states.dg
1878
+ dg(-9.0)
1879
+ >>> aides.dveq
1880
+ dveq(-99.0)
1881
+
1882
+ Technical checks:
1883
+
1884
+ As mentioned above, method |Return_ErrorDV_V1| changes the values of the
1885
+ sequences |DG| and |DVEq|, but only temporarily. Hence, we do not include
1886
+ them in the method specifications, even if the following check considers this
1887
+ erroneous:
1888
+
1889
+ >>> from hydpy.core.testtools import check_selectedvariables
1890
+ >>> from hydpy.models.wland.wland_model import Return_ErrorDV_V1
1891
+ >>> print(check_selectedvariables(Return_ErrorDV_V1))
1892
+ Definitely missing: dg and dveq
1893
+ Possibly missing (REQUIREDSEQUENCES):
1894
+ Calc_DVEq_V3: DG
1895
+ Possibly missing (RESULTSEQUENCES):
1896
+ Calc_DVEq_V3: DVEq
1897
+ """
1898
+
1899
+ CONTROLPARAMETERS = (
1900
+ wland_control.ThetaS,
1901
+ wland_control.ThetaR,
1902
+ wland_control.PsiAE,
1903
+ wland_control.B,
1904
+ )
1905
+ DERIVEDPARAMETERS = (wland_derived.NUG,)
1906
+ REQUIREDSEQUENCES = (wland_states.DV,)
1907
+ SUBMETHODS = (Calc_DVEq_V3,)
1908
+
1909
+ @staticmethod
1910
+ def __call__(model: modeltools.Model, dg: float) -> float:
1911
+ sta = model.sequences.states.fastaccess
1912
+ aid = model.sequences.aides.fastaccess
1913
+ dveq_old: float = aid.dveq
1914
+ dg_old: float = sta.dg
1915
+ sta.dg = dg
1916
+ model.calc_dveq_v3()
1917
+ d_delta: float = aid.dveq - sta.dv
1918
+ aid.dveq = dveq_old
1919
+ sta.dg = dg_old
1920
+ return d_delta
1921
+
1922
+
1923
+ class Calc_DGEq_V1(modeltools.Method):
1924
+ r"""Calculate the equilibrium groundwater depth.
1925
+
1926
+ Method |Calc_DGEq_V1| calculates the equilibrium groundwater depth for the
1927
+ current water deficit of the vadose zone, following methods |Return_DVH_V2|
1928
+ and |Calc_DVEq_V3|. As we are not aware of an analytical solution, we solve
1929
+ it numerically via class |PegasusDGEq|, which performs an iterative root-search
1930
+ based on the `Pegasus method`_.
1931
+
1932
+ Examples:
1933
+
1934
+ >>> from hydpy.models.wland import *
1935
+ >>> parameterstep()
1936
+ >>> thetas(0.4)
1937
+ >>> thetar(0.01)
1938
+ >>> psiae(300.0)
1939
+ >>> b(5.0)
1940
+ >>> from hydpy import UnitTest
1941
+ >>> test = UnitTest(
1942
+ ... model=model,
1943
+ ... method=model.calc_dgeq_v1,
1944
+ ... last_example=13,
1945
+ ... parseqs=(states.dv, aides.dgeq)
1946
+ ... )
1947
+ >>> test.nexts.dv = (
1948
+ ... -1.0, -0.01, 0.0, 0.01, 1.0, 2.0, 2.99, 3.0,
1949
+ ... 3.01012983, 5.1529353, 28.71839324, 111.1720584, 337.5798671)
1950
+ >>> test()
1951
+ | ex. | dv | dgeq |
1952
+ -----------------------------
1953
+ | 1 | -1.0 | 0.0 |
1954
+ | 2 | -0.01 | 0.0 |
1955
+ | 3 | 0.0 | 0.0 |
1956
+ | 4 | 0.01 | 1.0 |
1957
+ | 5 | 1.0 | 100.0 |
1958
+ | 6 | 2.0 | 200.0 |
1959
+ | 7 | 2.99 | 299.0 |
1960
+ | 8 | 3.0 | 300.0 |
1961
+ | 9 | 3.01013 | 301.0 |
1962
+ | 10 | 5.152935 | 400.0 |
1963
+ | 11 | 28.718393 | 800.0 |
1964
+ | 12 | 111.172058 | 1600.0 |
1965
+ | 13 | 337.579867 | 3200.0 |
1966
+ """
1967
+
1968
+ CONTROLPARAMETERS = (
1969
+ wland_control.ThetaS,
1970
+ wland_control.ThetaR,
1971
+ wland_control.PsiAE,
1972
+ wland_control.B,
1973
+ )
1974
+ DERIVEDPARAMETERS = (wland_derived.NUG,)
1975
+ REQUIREDSEQUENCES = (wland_states.DV,)
1976
+ RESULTSEQUENCES = (wland_aides.DGEq,)
1977
+ SUBMETHODS = (Return_ErrorDV_V1,)
1978
+
1979
+ @staticmethod
1980
+ def __call__(model: modeltools.Model) -> None:
1981
+ con = model.parameters.control.psiae.fastaccess
1982
+ sta = model.sequences.states.fastaccess
1983
+ aid = model.sequences.aides.fastaccess
1984
+ if sta.dv > 0.0:
1985
+ error: float = model.return_errordv_v1(con.psiae)
1986
+ if error <= 0.0:
1987
+ aid.dgeq = model.pegasusdgeq.find_x(
1988
+ con.psiae, 10000.0, con.psiae, 1000000.0, 0.0, 1e-8, 20
1989
+ )
1990
+ else:
1991
+ aid.dgeq = model.pegasusdgeq.find_x(
1992
+ 0.0, con.psiae, 0.0, con.psiae, 0.0, 1e-8, 20
1993
+ )
1994
+ else:
1995
+ aid.dgeq = 0.0
1996
+
1997
+
1998
+ class Calc_GF_V1(modeltools.Method):
1999
+ r"""Calculate the gain factor for changes in groundwater depth.
2000
+
2001
+ Basic equation (discontinuous):
2002
+ .. math::
2003
+ GF = \begin{cases}
2004
+ 0 &|\ DG \leq 0
2005
+ \\
2006
+ Return\_DVH\_V2(DGEq - DG)^{-1} &|\ 0 < DG
2007
+ \end{cases}
2008
+
2009
+ The original `WALRUS`_ model attributes a passive role to groundwater dynamics.
2010
+ All water entering or leaving the underground is added to or subtracted from the
2011
+ vadose zone, and the groundwater table only reacts to such changes until it is in
2012
+ equilibrium with the updated water deficit in the vadose zone. Hence, the movement
2013
+ of the groundwater table is generally slow. However, in catchments with
2014
+ near-surface water tables, we often observe fast responses of groundwater to input
2015
+ forcings, maybe due to rapid infiltration along macropores or the re-infiltration
2016
+ of channel water. In such situations, where the input water somehow bypasses the
2017
+ vadose zone, the speed of the rise of the groundwater table depends not only on
2018
+ the effective pore size of the soil material but also on the soil's degree of
2019
+ saturation directly above the groundwater table. The smaller the remaining pore
2020
+ size, the larger the fraction between the water table's rise and the actual
2021
+ groundwater recharge. We call this fraction the "gain factor" (|GF|).
2022
+
2023
+ The `WALRUS`_ model does not explicitly account for the soil moisture in different
2024
+ depths above the groundwater table. To keep the vertically lumped approach, we
2025
+ use the difference between the actual (|DG|) and the equilibrium groundwater depth
2026
+ (|DGEq|) as an indicator for the wetness above the groundwater table. When |DG|
2027
+ is identical to |DGEq|, soil moisture and groundwater are in equilibrium. Then,
2028
+ the tension-saturated area is fully developed, and the groundwater table moves
2029
+ quickly (depending on |ThetaR|). The opposite case is when |DG| is much smaller
2030
+ than |DGEq|. Such a situation occurs after a fast rise of the groundwater table
2031
+ when the soil water still needs much redistribution before it can be in equilibrium
2032
+ with groundwater. In the most extreme case, the gain factor is just as large as
2033
+ indicated by the effective pore size alone (depending on |ThetaS|).
2034
+
2035
+ The above discussion only applies as long as the groundwater table is below the
2036
+ soil surface. For large-scale ponding (see :cite:t:`ref-Brauer2014`, section 5.11),
2037
+ we set |GF| to zero. See the documentation on the methods |Calc_CDG_V1| and
2038
+ |Calc_FGS_V1| for related discussions.
2039
+
2040
+ Examples:
2041
+
2042
+ >>> from hydpy.models.wland import *
2043
+ >>> parameterstep()
2044
+ >>> thetas(0.4)
2045
+ >>> thetar(0.01)
2046
+ >>> psiae(300.0)
2047
+ >>> b(5.0)
2048
+ >>> sh(0.0)
2049
+ >>> aides.dgeq = 5000.0
2050
+ >>> derived.rh1.update()
2051
+ >>> from hydpy import UnitTest
2052
+ >>> test = UnitTest(
2053
+ ... model=model,
2054
+ ... method=model.calc_gf_v1,
2055
+ ... last_example=16,
2056
+ ... parseqs=(states.dg, aides.gf)
2057
+ ... )
2058
+ >>> test.nexts.dg = (
2059
+ ... -10.0, -1.0, 0.0, 1.0, 10.0,
2060
+ ... 1000.0, 2000.0, 3000.0, 4000.0, 4500.0, 4600.0,
2061
+ ... 4690.0, 4699.0, 4700.0, 4701.0, 4710.0)
2062
+ >>> test()
2063
+ | ex. | dg | gf |
2064
+ ----------------------------
2065
+ | 1 | -10.0 | 0.0 |
2066
+ | 2 | -1.0 | 0.0 |
2067
+ | 3 | 0.0 | 2.81175 |
2068
+ | 4 | 1.0 | 5.623782 |
2069
+ | 5 | 10.0 | 5.626316 |
2070
+ | 6 | 1000.0 | 5.963555 |
2071
+ | 7 | 2000.0 | 6.496601 |
2072
+ | 8 | 3000.0 | 7.510869 |
2073
+ | 9 | 4000.0 | 10.699902 |
2074
+ | 10 | 4500.0 | 20.88702 |
2075
+ | 11 | 4600.0 | 31.440737 |
2076
+ | 12 | 4690.0 | 79.686112 |
2077
+ | 13 | 4699.0 | 97.470815 |
2078
+ | 14 | 4700.0 | 100.0 |
2079
+ | 15 | 4701.0 | 100.0 |
2080
+ | 16 | 4710.0 | 100.0 |
2081
+
2082
+ >>> sh(1.0)
2083
+ >>> derived.rh1.update()
2084
+ >>> test()
2085
+ | ex. | dg | gf |
2086
+ ----------------------------
2087
+ | 1 | -10.0 | 0.0 |
2088
+ | 2 | -1.0 | 0.056232 |
2089
+ | 3 | 0.0 | 2.81175 |
2090
+ | 4 | 1.0 | 5.567544 |
2091
+ | 5 | 10.0 | 5.626316 |
2092
+ | 6 | 1000.0 | 5.963555 |
2093
+ | 7 | 2000.0 | 6.496601 |
2094
+ | 8 | 3000.0 | 7.510869 |
2095
+ | 9 | 4000.0 | 10.699902 |
2096
+ | 10 | 4500.0 | 20.88702 |
2097
+ | 11 | 4600.0 | 31.440737 |
2098
+ | 12 | 4690.0 | 79.686112 |
2099
+ | 13 | 4699.0 | 97.465434 |
2100
+ | 14 | 4700.0 | 99.609455 |
2101
+ | 15 | 4701.0 | 99.994314 |
2102
+ | 16 | 4710.0 | 100.0 |
2103
+ """
2104
+
2105
+ CONTROLPARAMETERS = (
2106
+ wland_control.ThetaS,
2107
+ wland_control.ThetaR,
2108
+ wland_control.PsiAE,
2109
+ wland_control.B,
2110
+ )
2111
+ DERIVEDPARAMETERS = (wland_derived.RH1,)
2112
+ REQUIREDSEQUENCES = (wland_states.DG, wland_aides.DGEq)
2113
+ RESULTSEQUENCES = (wland_aides.GF,)
2114
+ SUBMETHODS = (Return_DVH_V2,)
2115
+
2116
+ @staticmethod
2117
+ def __call__(model: modeltools.Model) -> None:
2118
+ der = model.parameters.derived.fastaccess
2119
+ sta = model.sequences.states.fastaccess
2120
+ aid = model.sequences.aides.fastaccess
2121
+ aid.gf = smoothutils.smooth_logistic1(sta.dg, der.rh1) / model.return_dvh_v2(
2122
+ aid.dgeq - sta.dg
2123
+ )
2124
+
2125
+
2126
+ class Calc_GR_V1(modeltools.Method):
2127
+ r"""Calculate the elevated region's groundwater recharge.
2128
+
2129
+ Basic equations (discontinous):
2130
+
2131
+ .. math::
2132
+ GR = \begin{cases}
2133
+ 0 &|\ AC \leq DV\!E \\
2134
+ AC - DV\!E &|\ AC > DV\!E
2135
+ \end{cases}
2136
+
2137
+ Examples:
2138
+
2139
+ >>> from hydpy.models.wland import *
2140
+ >>> parameterstep()
2141
+ >>> ac(200.0)
2142
+ >>> rg(False)
2143
+ >>> from hydpy import UnitTest
2144
+ >>> test = UnitTest(model=model,
2145
+ ... method=model.calc_gr_v1,
2146
+ ... last_example=7,
2147
+ ... parseqs=(states.dve, fluxes.gr))
2148
+ >>> test.nexts.dve = (100.0, 190.0, 199.0, 200.0, 201.0, 210.0, 300.0)
2149
+
2150
+ Discontinuous example:
2151
+
2152
+ >>> sh(0.0)
2153
+ >>> derived.rh2.update()
2154
+ >>> test()
2155
+ | ex. | dve | gr |
2156
+ -----------------------
2157
+ | 1 | 100.0 | 100.0 |
2158
+ | 2 | 190.0 | 10.0 |
2159
+ | 3 | 199.0 | 1.0 |
2160
+ | 4 | 200.0 | 0.0 |
2161
+ | 5 | 201.0 | 0.0 |
2162
+ | 6 | 210.0 | 0.0 |
2163
+ | 7 | 300.0 | 0.0 |
2164
+
2165
+ Continuous example:
2166
+
2167
+ >>> sh(10.0)
2168
+ >>> derived.rh2.update()
2169
+ >>> test()
2170
+ | ex. | dve | gr |
2171
+ --------------------------
2172
+ | 1 | 100.0 | 100.0 |
2173
+ | 2 | 190.0 | 10.01 |
2174
+ | 3 | 199.0 | 1.885788 |
2175
+ | 4 | 200.0 | 1.320935 |
2176
+ | 5 | 201.0 | 0.885788 |
2177
+ | 6 | 210.0 | 0.01 |
2178
+ | 7 | 300.0 | 0.0 |
2179
+ """
2180
+
2181
+ CONTROLPARAMETERS = (wland_control.AC,)
2182
+ DERIVEDPARAMETERS = (wland_derived.NUGE, wland_derived.RH2)
2183
+ REQUIREDSEQUENCES = (wland_states.DVE,)
2184
+ RESULTSEQUENCES = (wland_fluxes.GR,)
2185
+
2186
+ @staticmethod
2187
+ def __call__(model: modeltools.Model) -> None:
2188
+ con = model.parameters.control.fastaccess
2189
+ der = model.parameters.derived.fastaccess
2190
+ flu = model.sequences.fluxes.fastaccess
2191
+ sta = model.sequences.states.fastaccess
2192
+ if der.nuge:
2193
+ flu.gr = smoothutils.smooth_logistic2(con.ac - sta.dve, der.rh2)
2194
+ else:
2195
+ flu.gr = 0.0
2196
+
2197
+
2198
+ class Calc_CDG_V1(modeltools.Method):
2199
+ r"""Calculate the change in the groundwater depth due to percolation and
2200
+ capillary rise.
2201
+
2202
+ Basic equation (discontinuous):
2203
+ .. math::
2204
+ CDG = \frac{DV - min(DV\!Eq, \ DG)}{CV} + \begin{cases}
2205
+ \frac{FGS - FGSE - FXG}{ThetaS} &|\ DGC \\
2206
+ 0 &|\ \overline{DGC}
2207
+ \end{cases}
2208
+
2209
+ Note that this equation differs in two respects from equation 6 of
2210
+ :cite:t:`ref-Brauer2014`.
2211
+
2212
+ First, in the case of large-scale ponding, |DVEq| always stays at zero, and we let
2213
+ |DG| take control of the speed of the water table movement. See the documentation
2214
+ on method |Calc_FGS_V1| for additional information on the differences between
2215
+ |wland| and `WALRUS`_ for this rare situation.
2216
+
2217
+ Second, one can set |DGC| to |True| to enforce a more direct connection between the
2218
+ groundwater and surface water storage level. According to :cite:t:`ref-Brauer2014`,
2219
+ groundwater drainage and extraction increase and surface water infiltration and
2220
+ seepage decrease the water deficit in the vadose zone but do not change groundwater
2221
+ depth directly. This abstraction is as if, for example, groundwater drainage would
2222
+ take water from the soil's top. The groundwater level only reacts with some delay
2223
+ due to its tendency to advance towards the increased equilibrium depth. With |DGC|
2224
+ enabled, the mentioned fluxes change the vadose zone's deficit and the groundwater
2225
+ depth simultaneously.
2226
+
2227
+ Examples:
2228
+
2229
+ Without large-scale ponding and a direct groundwater connection:
2230
+
2231
+ >>> from hydpy.models.wland import *
2232
+ >>> simulationstep("12h")
2233
+ >>> parameterstep("1d")
2234
+ >>> dgc(False)
2235
+ >>> cv(10.0)
2236
+ >>> thetas(0.5)
2237
+ >>> sh(0.0)
2238
+ >>> derived.rh1.update()
2239
+ >>> states.dv = 100.0
2240
+ >>> states.dg = 1000.0
2241
+ >>> fluxes.fgs = 2.0
2242
+ >>> fluxes.fgse = 0.5
2243
+ >>> fluxes.fxg = 2.5
2244
+ >>> aides.dveq = 80.0
2245
+ >>> model.calc_cdg_v1()
2246
+ >>> fluxes.cdg
2247
+ cdg(1.0)
2248
+
2249
+ Without large-scale ponding and with a direct groundwater connection:
2250
+
2251
+ >>> dgc(True)
2252
+ >>> model.calc_cdg_v1()
2253
+ >>> fluxes.cdg
2254
+ cdg(-1.0)
2255
+
2256
+ With large-scale ponding and without smoothing:
2257
+
2258
+ >>> from hydpy import UnitTest
2259
+ >>> test = UnitTest(
2260
+ ... model=model,
2261
+ ... method=model.calc_cdg_v1,
2262
+ ... last_example=5,
2263
+ ... parseqs=(states.dg, fluxes.cdg)
2264
+ ... )
2265
+ >>> dgc(False)
2266
+ >>> states.dv = -10.0
2267
+ >>> aides.dveq = 0.0
2268
+ >>> test.nexts.dg = 10.0, 1.0, 0.0, -1.0, -10.0
2269
+ >>> test()
2270
+ | ex. | dg | cdg |
2271
+ -----------------------
2272
+ | 1 | 10.0 | -0.5 |
2273
+ | 2 | 1.0 | -0.5 |
2274
+ | 3 | 0.0 | -0.5 |
2275
+ | 4 | -1.0 | -0.45 |
2276
+ | 5 | -10.0 | 0.0 |
2277
+
2278
+ With large-scale ponding and smoothing:
2279
+
2280
+ >>> sh(1.0)
2281
+ >>> derived.rh1.update()
2282
+ >>> test()
2283
+ | ex. | dg | cdg |
2284
+ ---------------------------
2285
+ | 1 | 10.0 | -0.5 |
2286
+ | 2 | 1.0 | -0.499891 |
2287
+ | 3 | 0.0 | -0.492458 |
2288
+ | 4 | -1.0 | -0.449891 |
2289
+ | 5 | -10.0 | 0.0 |
2290
+ """
2291
+
2292
+ CONTROLPARAMETERS = (wland_control.CV, wland_control.ThetaS, wland_control.DGC)
2293
+ DERIVEDPARAMETERS = (wland_derived.NUG, wland_derived.RH1)
2294
+ REQUIREDSEQUENCES = (
2295
+ wland_states.DG,
2296
+ wland_states.DV,
2297
+ wland_fluxes.FGS,
2298
+ wland_fluxes.FGSE,
2299
+ wland_fluxes.FXG,
2300
+ wland_aides.DVEq,
2301
+ )
2302
+ RESULTSEQUENCES = (wland_fluxes.CDG,)
2303
+
2304
+ @staticmethod
2305
+ def __call__(model: modeltools.Model) -> None:
2306
+ con = model.parameters.control.fastaccess
2307
+ der = model.parameters.derived.fastaccess
2308
+ flu = model.sequences.fluxes.fastaccess
2309
+ sta = model.sequences.states.fastaccess
2310
+ aid = model.sequences.aides.fastaccess
2311
+ if der.nug:
2312
+ target: float = smoothutils.smooth_min1(aid.dveq, sta.dg, der.rh1)
2313
+ flu.cdg = (sta.dv - target) / con.cv
2314
+ if con.dgc:
2315
+ flu.cdg += (flu.fgs - flu.fgse - flu.fxg) / con.thetas
2316
+ else:
2317
+ flu.cdg = 0.0
2318
+
2319
+
2320
+ class Calc_CDG_V2(modeltools.Method):
2321
+ r"""Calculate the vadose zone's storage deficit change due to percolation,
2322
+ capillary rise, macropore infiltration, seepage, groundwater flow, and channel
2323
+ water infiltration.
2324
+
2325
+ Basic equation:
2326
+ :math:`CDG =
2327
+ \frac{DV-min(DV\!Eq, \ DG)}{CV} + GF \cdot \big( FGS - FGSE - PV - FXG \big)`
2328
+
2329
+ Method |Calc_CDG_V2| extends |Calc_CDG_V1|, which implements the (nearly) original
2330
+ `WALRUS`_ relationship defined by equation 6 of :cite:t:`ref-Brauer2014`). See the
2331
+ documentation on method |Calc_GF_V1| for a comprehensive explanation of the reason
2332
+ for this extension.
2333
+
2334
+ Examples:
2335
+
2336
+ Without large-scale ponding:
2337
+
2338
+ >>> from hydpy.models.wland import *
2339
+ >>> simulationstep("12h")
2340
+ >>> parameterstep("1d")
2341
+ >>> cv(10.0)
2342
+ >>> sh(0.0)
2343
+ >>> derived.rh1.update()
2344
+ >>> states.dv = 100.0
2345
+ >>> states.dg = 1000.0
2346
+ >>> fluxes.pv = 1.0
2347
+ >>> fluxes.fxg = 0.5
2348
+ >>> fluxes.fgse = 1.5
2349
+ >>> fluxes.fgs = 4.0
2350
+ >>> aides.dveq = 80.0
2351
+ >>> aides.gf = 2.0
2352
+ >>> model.calc_cdg_v2()
2353
+ >>> fluxes.cdg
2354
+ cdg(3.0)
2355
+
2356
+ With large-scale ponding and without smoothing:
2357
+
2358
+ >>> from hydpy import UnitTest
2359
+ >>> test = UnitTest(
2360
+ ... model=model,
2361
+ ... method=model.calc_cdg_v2,
2362
+ ... last_example=5,
2363
+ ... parseqs=(states.dg, fluxes.cdg)
2364
+ ... )
2365
+ >>> aides.gf = 0.0
2366
+ >>> states.dv = -10.0
2367
+ >>> aides.dveq = 0.0
2368
+ >>> test.nexts.dg = 10.0, 1.0, 0.0, -1.0, -10.0
2369
+ >>> test()
2370
+ | ex. | dg | cdg |
2371
+ -----------------------
2372
+ | 1 | 10.0 | -0.5 |
2373
+ | 2 | 1.0 | -0.5 |
2374
+ | 3 | 0.0 | -0.5 |
2375
+ | 4 | -1.0 | -0.45 |
2376
+ | 5 | -10.0 | 0.0 |
2377
+
2378
+ With large-scale ponding and with smoothing:
2379
+
2380
+ >>> sh(1.0)
2381
+ >>> derived.rh1.update()
2382
+ >>> test()
2383
+ | ex. | dg | cdg |
2384
+ ---------------------------
2385
+ | 1 | 10.0 | -0.5 |
2386
+ | 2 | 1.0 | -0.499891 |
2387
+ | 3 | 0.0 | -0.492458 |
2388
+ | 4 | -1.0 | -0.449891 |
2389
+ | 5 | -10.0 | 0.0 |
2390
+ """
2391
+
2392
+ CONTROLPARAMETERS = (wland_control.CV,)
2393
+ DERIVEDPARAMETERS = (wland_derived.NUG, wland_derived.RH1)
2394
+ REQUIREDSEQUENCES = (
2395
+ wland_fluxes.PV,
2396
+ wland_fluxes.FGS,
2397
+ wland_fluxes.FGSE,
2398
+ wland_fluxes.FXG,
2399
+ wland_states.DG,
2400
+ wland_states.DV,
2401
+ wland_aides.DVEq,
2402
+ wland_aides.GF,
2403
+ )
2404
+ RESULTSEQUENCES = (wland_fluxes.CDG,)
2405
+
2406
+ @staticmethod
2407
+ def __call__(model: modeltools.Model) -> None:
2408
+ con = model.parameters.control.fastaccess
2409
+ der = model.parameters.derived.fastaccess
2410
+ flu = model.sequences.fluxes.fastaccess
2411
+ sta = model.sequences.states.fastaccess
2412
+ aid = model.sequences.aides.fastaccess
2413
+ if der.nug:
2414
+ target: float = smoothutils.smooth_min1(aid.dveq, sta.dg, der.rh1)
2415
+ cdg_slow: float = (sta.dv - target) / con.cv
2416
+ cdg_fast: float = aid.gf * (flu.fgs - flu.fgse - flu.pv - flu.fxg)
2417
+ flu.cdg = cdg_slow + cdg_fast
2418
+ else:
2419
+ flu.cdg = 0.0
2420
+
2421
+
2422
+ class Calc_FGSE_V1(modeltools.Method):
2423
+ r"""Calculate the groundwater flow between the elevated and the lowland regions.
2424
+
2425
+ The basic equation of method |Calc_FGSE_V1| relies on the one of |Calc_FGS_V1|
2426
+ introduced by :cite:t:`ref-Brauer2014`. We decided so to calculate |FGSE| in a
2427
+ WALRUS-like manner.
2428
+
2429
+ Basic equation:
2430
+
2431
+ .. math::
2432
+ FGSE = \frac{\Delta \cdot |\Delta|}{CGE}
2433
+ \\\\
2434
+ \Delta = HGE - (1000 \cdot GL - DG)
2435
+
2436
+ Examples:
2437
+
2438
+ >>> from hydpy.models.wland import *
2439
+ >>> simulationstep("12h")
2440
+ >>> parameterstep("1d")
2441
+ >>> gl(5.0)
2442
+ >>> cge(1000000.0)
2443
+ >>> states.dg = 3000.0
2444
+
2445
+ Normal flow:
2446
+
2447
+ >>> states.hge = 4000.0
2448
+ >>> model.calc_fgse_v1()
2449
+ >>> fluxes.fgse
2450
+ fgse(2.0)
2451
+
2452
+ No flow:
2453
+
2454
+ >>> states.hge = 2000.0
2455
+ >>> model.calc_fgse_v1()
2456
+ >>> fluxes.fgse
2457
+ fgse(0.0)
2458
+
2459
+ Reversed flow:
2460
+
2461
+ >>> states.hge = 0.0
2462
+ >>> model.calc_fgse_v1()
2463
+ >>> fluxes.fgse
2464
+ fgse(-2.0)
2465
+ """
2466
+
2467
+ CONTROLPARAMETERS = (wland_control.GL, wland_control.CGE)
2468
+ DERIVEDPARAMETERS = (wland_derived.NUGE,)
2469
+ REQUIREDSEQUENCES = (wland_states.HGE, wland_states.DG)
2470
+ RESULTSEQUENCES = (wland_fluxes.FGSE,)
2471
+
2472
+ @staticmethod
2473
+ def __call__(model: modeltools.Model) -> None:
2474
+ con = model.parameters.control.fastaccess
2475
+ der = model.parameters.derived.fastaccess
2476
+ flu = model.sequences.fluxes.fastaccess
2477
+ sta = model.sequences.states.fastaccess
2478
+ if der.nuge:
2479
+ hge: float = sta.hge
2480
+ hg: float = 1000.0 * con.gl - sta.dg
2481
+ flu.fgse = modelutils.fabs(hge - hg) * (hge - hg) / con.cge
2482
+ else:
2483
+ flu.fgse = 0.0
2484
+
2485
+
2486
+ class Calc_FGS_V1(modeltools.Method):
2487
+ r"""Calculate the groundwater drainage or surface water infiltration.
2488
+
2489
+ For large-scale ponding, |wland| and `WALRUS`_ calculate |FGS| differently
2490
+ (even for discontinuous parameterisations). In such cases, he `WALRUS`_ model
2491
+ redistributes water instantaneously (see :cite:t:`ref-Brauer2014`, section 5.11),
2492
+ which relates to infinitely high flow velocities and cannot be handled by the
2493
+ numerical integration algorithm underlying |wland|. Hence, we introduce the
2494
+ parameter |CGF| instead. Setting it to a value larger than zero increases the flow
2495
+ velocity with increasing large-scale ponding. The larger the value of |CGF|,
2496
+ the stronger the functional similarity of both approaches. But note that very
2497
+ high values can result in increased computation times.
2498
+
2499
+ Basic equations (discontinous):
2500
+
2501
+ .. math::
2502
+ FGS = Gradient \cdot ContactSurface \cdot Conductivity
2503
+ \\ \\
2504
+ HG^* = max(CD - DG, \ 0) \\
2505
+ HS^* = max(HS, \ 0) \\
2506
+ Gradient = \begin{cases}
2507
+ HG^* - HS^* &|\ RG \\
2508
+ CD - DG - HS^* &|\ \overline{RG} \\
2509
+ \end{cases} \\
2510
+ ContactSurface = \begin{cases}
2511
+ |HG^* - HS^*| &|\ RG \\
2512
+ max(HG^*, \ HS^*) &|\ \overline{RG} \\
2513
+ \end{cases} \\
2514
+ Excess = max(-DG, HS - CD, \ 0) \\
2515
+ Conductivity = (1 + CGF \cdot Excess) / CG
2516
+
2517
+ Examples:
2518
+
2519
+ >>> from hydpy.models.wland import *
2520
+ >>> simulationstep("12h")
2521
+ >>> parameterstep("1d")
2522
+ >>> cg(10000.0)
2523
+ >>> rg(False)
2524
+ >>> derived.cd(600.0)
2525
+ >>> states.hs = 300.0
2526
+ >>> from hydpy import UnitTest
2527
+ >>> test = UnitTest(model=model,
2528
+ ... method=model.calc_fgs_v1,
2529
+ ... last_example=15,
2530
+ ... parseqs=(states.dg, states.hs, fluxes.fgs))
2531
+ >>> test.nexts.dg = (
2532
+ ... -100.0, -1.0, 0.0, 1.0, 100.0, 200.0, 290.0, 299.0,
2533
+ ... 300.0, 301.0, 310.0, 400.0, 500.0, 600.0, 700.0)
2534
+
2535
+ Without smoothing and without increased conductivity for large-scale ponding:
2536
+
2537
+ >>> cgf(0.0)
2538
+ >>> sh(0.0)
2539
+ >>> derived.rh2.update()
2540
+ >>> test()
2541
+ | ex. | dg | hs | fgs |
2542
+ ----------------------------------
2543
+ | 1 | -100.0 | 300.0 | 14.0 |
2544
+ | 2 | -1.0 | 300.0 | 9.04505 |
2545
+ | 3 | 0.0 | 300.0 | 9.0 |
2546
+ | 4 | 1.0 | 300.0 | 8.95505 |
2547
+ | 5 | 100.0 | 300.0 | 5.0 |
2548
+ | 6 | 200.0 | 300.0 | 2.0 |
2549
+ | 7 | 290.0 | 300.0 | 0.155 |
2550
+ | 8 | 299.0 | 300.0 | 0.01505 |
2551
+ | 9 | 300.0 | 300.0 | 0.0 |
2552
+ | 10 | 301.0 | 300.0 | -0.015 |
2553
+ | 11 | 310.0 | 300.0 | -0.15 |
2554
+ | 12 | 400.0 | 300.0 | -1.5 |
2555
+ | 13 | 500.0 | 300.0 | -3.0 |
2556
+ | 14 | 600.0 | 300.0 | -4.5 |
2557
+ | 15 | 700.0 | 300.0 | -6.0 |
2558
+
2559
+ Without smoothing but with increased conductivity for large-scale ponding:
2560
+
2561
+ >>> cgf(0.1)
2562
+ >>> test()
2563
+ | ex. | dg | hs | fgs |
2564
+ -----------------------------------
2565
+ | 1 | -100.0 | 300.0 | 294.0 |
2566
+ | 2 | -1.0 | 300.0 | 10.85406 |
2567
+ | 3 | 0.0 | 300.0 | 9.0 |
2568
+ | 4 | 1.0 | 300.0 | 8.95505 |
2569
+ | 5 | 100.0 | 300.0 | 5.0 |
2570
+ | 6 | 200.0 | 300.0 | 2.0 |
2571
+ | 7 | 290.0 | 300.0 | 0.155 |
2572
+ | 8 | 299.0 | 300.0 | 0.01505 |
2573
+ | 9 | 300.0 | 300.0 | 0.0 |
2574
+ | 10 | 301.0 | 300.0 | -0.015 |
2575
+ | 11 | 310.0 | 300.0 | -0.15 |
2576
+ | 12 | 400.0 | 300.0 | -1.5 |
2577
+ | 13 | 500.0 | 300.0 | -3.0 |
2578
+ | 14 | 600.0 | 300.0 | -4.5 |
2579
+ | 15 | 700.0 | 300.0 | -6.0 |
2580
+
2581
+ With smoothing and with increased conductivity for large-scale ponding:
2582
+
2583
+ >>> sh(1.0)
2584
+ >>> derived.rh2.update()
2585
+ >>> test()
2586
+ | ex. | dg | hs | fgs |
2587
+ -----------------------------------
2588
+ | 1 | -100.0 | 300.0 | 294.0 |
2589
+ | 2 | -1.0 | 300.0 | 10.87215 |
2590
+ | 3 | 0.0 | 300.0 | 9.369944 |
2591
+ | 4 | 1.0 | 300.0 | 8.97296 |
2592
+ | 5 | 100.0 | 300.0 | 5.0 |
2593
+ | 6 | 200.0 | 300.0 | 2.0 |
2594
+ | 7 | 290.0 | 300.0 | 0.155 |
2595
+ | 8 | 299.0 | 300.0 | 0.01505 |
2596
+ | 9 | 300.0 | 300.0 | 0.0 |
2597
+ | 10 | 301.0 | 300.0 | -0.015 |
2598
+ | 11 | 310.0 | 300.0 | -0.15 |
2599
+ | 12 | 400.0 | 300.0 | -1.5 |
2600
+ | 13 | 500.0 | 300.0 | -3.0 |
2601
+ | 14 | 600.0 | 300.0 | -4.5 |
2602
+ | 15 | 700.0 | 300.0 | -6.0 |
2603
+
2604
+ Another difference to the original WALRUS model is optional. Enabling the |RG|
2605
+ option restricts the |FGS| in two ways. First, the groundwater depth used for
2606
+ calculating the gradient between the surface and the groundwater level is
2607
+ restricted to the channel depth so that extremely low groundwater levels do not
2608
+ result in extremely high surface water infiltration. Second, the contact
2609
+ surface is restricted to the difference between the surface and the
2610
+ (restricted) groundwater level so that uncertainties in channel depth estimates
2611
+ have a less severe effect both on groundwater drainage and surface water
2612
+ infiltration:
2613
+
2614
+ >>> rg(True)
2615
+ >>> test()
2616
+ | ex. | dg | hs | fgs |
2617
+ ------------------------------------
2618
+ | 1 | -100.0 | 300.0 | 168.0 |
2619
+ | 2 | -1.0 | 300.0 | 5.44512 |
2620
+ | 3 | 0.0 | 300.0 | 4.684972 |
2621
+ | 4 | 1.0 | 300.0 | 4.47899 |
2622
+ | 5 | 100.0 | 300.0 | 2.0 |
2623
+ | 6 | 200.0 | 300.0 | 0.5 |
2624
+ | 7 | 290.0 | 300.0 | 0.005 |
2625
+ | 8 | 299.0 | 300.0 | 0.00005 |
2626
+ | 9 | 300.0 | 300.0 | 0.0 |
2627
+ | 10 | 301.0 | 300.0 | -0.00005 |
2628
+ | 11 | 310.0 | 300.0 | -0.005 |
2629
+ | 12 | 400.0 | 300.0 | -0.5 |
2630
+ | 13 | 500.0 | 300.0 | -2.0 |
2631
+ | 14 | 600.0 | 300.0 | -4.493836 |
2632
+ | 15 | 700.0 | 300.0 | -4.5 |
2633
+
2634
+ """
2635
+
2636
+ CONTROLPARAMETERS = (wland_control.CG, wland_control.RG, wland_control.CGF)
2637
+ DERIVEDPARAMETERS = (wland_derived.CD, wland_derived.NUG, wland_derived.RH2)
2638
+ REQUIREDSEQUENCES = (wland_states.DG, wland_states.HS)
2639
+ RESULTSEQUENCES = (wland_fluxes.FGS,)
2640
+
2641
+ @staticmethod
2642
+ def __call__(model: modeltools.Model) -> None:
2643
+ con = model.parameters.control.fastaccess
2644
+ der = model.parameters.derived.fastaccess
2645
+ flu = model.sequences.fluxes.fastaccess
2646
+ sta = model.sequences.states.fastaccess
2647
+ if der.nug:
2648
+ hg: float = smoothutils.smooth_logistic2(der.cd - sta.dg, der.rh2)
2649
+ hs: float = smoothutils.smooth_logistic2(sta.hs, der.rh2)
2650
+ gradient: float = (hg if con.rg else der.cd - sta.dg) - hs
2651
+ if con.rg:
2652
+ contactsurface: float = modelutils.fabs(hg - hs)
2653
+ else:
2654
+ contactsurface = smoothutils.smooth_max1(hg, hs, der.rh2)
2655
+ excess: float = smoothutils.smooth_max2(
2656
+ -sta.dg, sta.hs - der.cd, 0.0, der.rh2
2657
+ )
2658
+ conductivity: float = (1.0 + con.cgf * excess) / con.cg
2659
+ flu.fgs = gradient * contactsurface * conductivity
2660
+ else:
2661
+ flu.fgs = 0.0
2662
+
2663
+
2664
+ class Calc_FQS_V1(modeltools.Method):
2665
+ r"""Calculate the quickflow.
2666
+
2667
+ Basic equation:
2668
+ :math:`FQS = \frac{HQ}{CQ}`
2669
+
2670
+ Examples:
2671
+
2672
+ >>> from hydpy.models.wland import *
2673
+ >>> simulationstep("12h")
2674
+ >>> parameterstep("1d")
2675
+ >>> nu(2)
2676
+ >>> cq(10.0)
2677
+ >>> states.hq = 100.0
2678
+ >>> model.calc_fqs_v1()
2679
+ >>> fluxes.fqs
2680
+ fqs(5.0)
2681
+
2682
+ Without land areas, quickflow is zero:
2683
+
2684
+ >>> nu(1)
2685
+ >>> model.calc_fqs_v1()
2686
+ >>> fluxes.fqs
2687
+ fqs(0.0)
2688
+ """
2689
+
2690
+ CONTROLPARAMETERS = (wland_control.NU, wland_control.CQ)
2691
+ REQUIREDSEQUENCES = (wland_states.HQ,)
2692
+ RESULTSEQUENCES = (wland_fluxes.FQS,)
2693
+
2694
+ @staticmethod
2695
+ def __call__(model: modeltools.Model) -> None:
2696
+ con = model.parameters.control.fastaccess
2697
+ flu = model.sequences.fluxes.fastaccess
2698
+ sta = model.sequences.states.fastaccess
2699
+ if con.nu > 1:
2700
+ flu.fqs = sta.hq / con.cq
2701
+ else:
2702
+ flu.fqs = 0.0
2703
+
2704
+
2705
+ class Calc_RH_V1(modeltools.Method):
2706
+ r"""Let a submodel that complies with the |DischargeModel_V2| interface calculate
2707
+ the runoff height or, if no such submodel is available, equate it with all other
2708
+ flows in and out of the surface water storage.
2709
+
2710
+ Basic equation (without submodel):
2711
+ :math:`RH = ASR \cdot (PS - ES + FXS) + ALR \cdot FQS + AGR \cdot FGS`
2712
+
2713
+ Examples:
2714
+
2715
+ >>> from hydpy.models.wland_wag import *
2716
+ >>> simulationstep("12h")
2717
+ >>> parameterstep("1d")
2718
+
2719
+ Without an available submodel, |Calc_RH_V1| applies the given basic equation:
2720
+
2721
+ >>> derived.asr(0.2)
2722
+ >>> derived.alr(0.8)
2723
+ >>> derived.agr(0.6)
2724
+ >>> fluxes.ps = 3.0
2725
+ >>> fluxes.fxs = 1.0
2726
+ >>> fluxes.es = 2.0
2727
+ >>> fluxes.fqs(0.5)
2728
+ >>> fluxes.fgs(0.2)
2729
+ >>> model.calc_rh_v1()
2730
+ >>> fluxes.rh
2731
+ rh(0.92)
2732
+
2733
+ We use |wq_walrus|, which implements WALRUS' standard approach for calculating
2734
+ |RH|, to demonstrate that |Calc_RH_V1| correctly uses submodels that follow the
2735
+ |DischargeModel_V2| interface:
2736
+
2737
+ >>> sh(0.1)
2738
+ >>> states.hs(3000.0)
2739
+ >>> derived.cd(5000.0)
2740
+ >>> with model.add_dischargemodel_v2("wq_walrus"):
2741
+ ... crestheight(2.0)
2742
+ ... bankfulldischarge(2.0)
2743
+ ... dischargeexponent(2.0)
2744
+ >>> model.calc_rh_v1()
2745
+ >>> fluxes.rh
2746
+ rh(0.111111)
2747
+ """
2748
+
2749
+ DERIVEDPARAMETERS = (wland_derived.ASR, wland_derived.ALR, wland_derived.AGR)
2750
+ REQUIREDSEQUENCES = (
2751
+ wland_fluxes.PS,
2752
+ wland_fluxes.ES,
2753
+ wland_fluxes.FXS,
2754
+ wland_fluxes.FQS,
2755
+ wland_fluxes.FGS,
2756
+ wland_states.HS,
2757
+ )
2758
+ RESULTSEQUENCES = (wland_fluxes.RH,)
2759
+
2760
+ @staticmethod
2761
+ def __call__(model: modeltools.Model) -> None:
2762
+ der = model.parameters.derived.fastaccess
2763
+ flu = model.sequences.fluxes.fastaccess
2764
+ sta = model.sequences.states.fastaccess
2765
+ if model.dischargemodel is None:
2766
+ flu.rh = (
2767
+ der.asr * (flu.fxs + flu.ps - flu.es)
2768
+ + der.alr * flu.fqs
2769
+ + der.agr * flu.fgs
2770
+ )
2771
+ elif model.dischargemodel_typeid == 2:
2772
+ flu.rh = cast(
2773
+ dischargeinterfaces.DischargeModel_V2, model.dischargemodel
2774
+ ).calculate_discharge(sta.hs / 1000.0)
2775
+
2776
+
2777
+ class Update_IC_V1(modeltools.Method):
2778
+ r"""Update the interception storage.
2779
+
2780
+ Basic equation:
2781
+ :math:`\frac{dIC}{dt} = PC - TF - EI`
2782
+
2783
+ Example:
2784
+
2785
+ >>> from hydpy.models.wland import *
2786
+ >>> parameterstep()
2787
+ >>> nu(2)
2788
+ >>> derived.nul.update()
2789
+ >>> fluxes.pc = 2.0
2790
+ >>> fluxes.tf = 1.0
2791
+ >>> fluxes.ei = 3.0
2792
+ >>> states.ic.old = 4.0
2793
+ >>> model.update_ic_v1()
2794
+ >>> states.ic
2795
+ ic(2.0, 0.0)
2796
+ """
2797
+
2798
+ DERIVEDPARAMETERS = (wland_derived.NUL,)
2799
+ REQUIREDSEQUENCES = (wland_fluxes.PC, wland_fluxes.TF, wland_fluxes.EI)
2800
+ UPDATEDSEQUENCES = (wland_states.IC,)
2801
+
2802
+ @staticmethod
2803
+ def __call__(model: modeltools.Model) -> None:
2804
+ der = model.parameters.derived.fastaccess
2805
+ flu = model.sequences.fluxes.fastaccess
2806
+ old = model.sequences.states.fastaccess_old
2807
+ new = model.sequences.states.fastaccess_new
2808
+ for k in range(der.nul):
2809
+ new.ic[k] = old.ic[k] + (flu.pc - flu.tf[k] - flu.ei[k])
2810
+ new.ic[der.nul] = 0
2811
+
2812
+
2813
+ class Update_SP_V1(modeltools.Method):
2814
+ r"""Update the storage deficit.
2815
+
2816
+ Basic equation:
2817
+ :math:`\frac{dSP}{dt} = SF - AM`
2818
+
2819
+ Example:
2820
+
2821
+ >>> from hydpy.models.wland import *
2822
+ >>> parameterstep()
2823
+ >>> nu(2)
2824
+ >>> derived.nul.update()
2825
+ >>> fluxes.sf = 1.0
2826
+ >>> fluxes.am = 2.0
2827
+ >>> states.sp.old = 3.0
2828
+ >>> model.update_sp_v1()
2829
+ >>> states.sp
2830
+ sp(2.0, 0.0)
2831
+ """
2832
+
2833
+ DERIVEDPARAMETERS = (wland_derived.NUL,)
2834
+ REQUIREDSEQUENCES = (wland_fluxes.SF, wland_fluxes.AM)
2835
+ UPDATEDSEQUENCES = (wland_states.SP,)
2836
+
2837
+ @staticmethod
2838
+ def __call__(model: modeltools.Model) -> None:
2839
+ der = model.parameters.derived.fastaccess
2840
+ flu = model.sequences.fluxes.fastaccess
2841
+ old = model.sequences.states.fastaccess_old
2842
+ new = model.sequences.states.fastaccess_new
2843
+ for k in range(der.nul):
2844
+ new.sp[k] = old.sp[k] + (flu.sf[k] - flu.am[k])
2845
+ new.sp[der.nul] = 0
2846
+
2847
+
2848
+ class Update_DVE_V1(modeltools.Method):
2849
+ r"""Update the elevated region's storage deficit of the vadose zone.
2850
+
2851
+ Basic equation:
2852
+ :math:`\frac{dDV\!E}{dt} = -(PV\!E - ETV\!E - GR)`
2853
+
2854
+ Examples:
2855
+
2856
+ >>> from hydpy.models.wland import *
2857
+ >>> parameterstep()
2858
+ >>> derived.nuge(1)
2859
+ >>> fluxes.pve = 1.0
2860
+ >>> fluxes.etve = 2.0
2861
+ >>> fluxes.gr = 3.0
2862
+ >>> states.dve.old = 5.0
2863
+ >>> model.update_dve_v1()
2864
+ >>> states.dve
2865
+ dve(9.0)
2866
+
2867
+ >>> derived.nuge(0)
2868
+ >>> model.update_dve_v1()
2869
+ >>> states.dve
2870
+ dve(nan)
2871
+ """
2872
+
2873
+ DERIVEDPARAMETERS = (wland_derived.NUGE,)
2874
+ REQUIREDSEQUENCES = (wland_fluxes.PVE, wland_fluxes.ETVE, wland_fluxes.GR)
2875
+ UPDATEDSEQUENCES = (wland_states.DVE,)
2876
+
2877
+ @staticmethod
2878
+ def __call__(model: modeltools.Model) -> None:
2879
+ der = model.parameters.derived.fastaccess
2880
+ flu = model.sequences.fluxes.fastaccess
2881
+ old = model.sequences.states.fastaccess_old
2882
+ new = model.sequences.states.fastaccess_new
2883
+ if der.nuge:
2884
+ new.dve = old.dve - (flu.pve - flu.etve - flu.gr)
2885
+ else:
2886
+ new.dve = modelutils.nan
2887
+
2888
+
2889
+ class Update_DV_V1(modeltools.Method):
2890
+ r"""Update the lowland region's storage deficit of the vadose zone.
2891
+
2892
+ Basic equation:
2893
+ :math:`\frac{dDV}{dt} =
2894
+ - \left( FXG + PV - ETV - FGS + FGSE \cdot \frac{AGRE}{AGR} \right)`
2895
+
2896
+ Example:
2897
+
2898
+ >>> from hydpy.models.wland import *
2899
+ >>> parameterstep()
2900
+ >>> derived.nug(1)
2901
+ >>> derived.agre(0.2)
2902
+ >>> derived.agr(0.4)
2903
+ >>> fluxes.fxg = 1.0
2904
+ >>> fluxes.pv = 2.0
2905
+ >>> fluxes.etv = 3.0
2906
+ >>> fluxes.fgs = 4.0
2907
+ >>> fluxes.fgse = 5.0
2908
+ >>> states.dv.old = 6.0
2909
+ >>> model.update_dv_v1()
2910
+ >>> states.dv
2911
+ dv(7.5)
2912
+
2913
+ >>> derived.nug(0)
2914
+ >>> model.update_dv_v1()
2915
+ >>> states.dv
2916
+ dv(nan)
2917
+ """
2918
+
2919
+ DERIVEDPARAMETERS = (wland_derived.NUG, wland_derived.AGRE, wland_derived.AGR)
2920
+ REQUIREDSEQUENCES = (
2921
+ wland_fluxes.FXG,
2922
+ wland_fluxes.PV,
2923
+ wland_fluxes.ETV,
2924
+ wland_fluxes.FGSE,
2925
+ wland_fluxes.FGS,
2926
+ )
2927
+ UPDATEDSEQUENCES = (wland_states.DV,)
2928
+
2929
+ @staticmethod
2930
+ def __call__(model: modeltools.Model) -> None:
2931
+ der = model.parameters.derived.fastaccess
2932
+ flu = model.sequences.fluxes.fastaccess
2933
+ old = model.sequences.states.fastaccess_old
2934
+ new = model.sequences.states.fastaccess_new
2935
+ if der.nug:
2936
+ new.dv = old.dv - (
2937
+ flu.fxg + flu.pv - flu.etv - flu.fgs + flu.fgse * der.agre / der.agr
2938
+ )
2939
+ else:
2940
+ new.dv = modelutils.nan
2941
+
2942
+
2943
+ class Update_HGE_V1(modeltools.Method):
2944
+ r"""Update the elevated region's groundwater level.
2945
+
2946
+ Basic equation:
2947
+ :math:`\frac{dDGE}{dt} = CDG`
2948
+
2949
+ Example:
2950
+
2951
+ >>> from hydpy.models.wland import *
2952
+ >>> parameterstep()
2953
+ >>> thetas(0.5)
2954
+ >>> derived.nuge(1)
2955
+ >>> fluxes.gr = 1.0
2956
+ >>> fluxes.fgse = 2.0
2957
+ >>> states.hge.old = 3.0
2958
+ >>> model.update_hge_v1()
2959
+ >>> states.hge
2960
+ hge(1.0)
2961
+
2962
+ >>> derived.nuge(0)
2963
+ >>> model.update_hge_v1()
2964
+ >>> states.hge
2965
+ hge(nan)
2966
+ """
2967
+
2968
+ CONTROLPARAMETERS = (wland_control.ThetaS,)
2969
+ DERIVEDPARAMETERS = (wland_derived.NUGE,)
2970
+ REQUIREDSEQUENCES = (wland_fluxes.GR, wland_fluxes.FGSE)
2971
+ UPDATEDSEQUENCES = (wland_states.HGE,)
2972
+
2973
+ @staticmethod
2974
+ def __call__(model: modeltools.Model) -> None:
2975
+ con = model.parameters.control.fastaccess
2976
+ der = model.parameters.derived.fastaccess
2977
+ flu = model.sequences.fluxes.fastaccess
2978
+ old = model.sequences.states.fastaccess_old
2979
+ new = model.sequences.states.fastaccess_new
2980
+ if der.nuge:
2981
+ new.hge = old.hge + (flu.gr - flu.fgse) / con.thetas
2982
+ else:
2983
+ new.hge = modelutils.nan
2984
+
2985
+
2986
+ class Update_DG_V1(modeltools.Method):
2987
+ r"""Update the lowland region's groundwater depth.
2988
+
2989
+ Basic equation:
2990
+ :math:`\frac{dDG}{dt} = CDG`
2991
+
2992
+ Example:
2993
+
2994
+ >>> from hydpy.models.wland import *
2995
+ >>> parameterstep()
2996
+ >>> derived.nug(1)
2997
+ >>> states.dg.old = 2.0
2998
+ >>> fluxes.cdg = 3.0
2999
+ >>> model.update_dg_v1()
3000
+ >>> states.dg
3001
+ dg(5.0)
3002
+
3003
+ >>> derived.nug(0)
3004
+ >>> model.update_dg_v1()
3005
+ >>> states.dg
3006
+ dg(nan)
3007
+ """
3008
+
3009
+ DERIVEDPARAMETERS = (wland_derived.NUG,)
3010
+ REQUIREDSEQUENCES = (wland_fluxes.CDG,)
3011
+ UPDATEDSEQUENCES = (wland_states.DG,)
3012
+
3013
+ @staticmethod
3014
+ def __call__(model: modeltools.Model) -> None:
3015
+ der = model.parameters.derived.fastaccess
3016
+ flu = model.sequences.fluxes.fastaccess
3017
+ old = model.sequences.states.fastaccess_old
3018
+ new = model.sequences.states.fastaccess_new
3019
+ if der.nug:
3020
+ new.dg = old.dg + flu.cdg
3021
+ else:
3022
+ new.dg = modelutils.nan
3023
+
3024
+
3025
+ class Update_HQ_V1(modeltools.Method):
3026
+ r"""Update the level of the quickflow reservoir.
3027
+
3028
+ Basic equation:
3029
+ :math:`\frac{dHQ}{dt} = PQ - FQS`
3030
+
3031
+ Example:
3032
+
3033
+ >>> from hydpy.models.wland import *
3034
+ >>> parameterstep()
3035
+ >>> states.hq.old = 2.0
3036
+ >>> fluxes.pq = 3.0
3037
+ >>> fluxes.fqs = 4.0
3038
+ >>> model.update_hq_v1()
3039
+ >>> states.hq
3040
+ hq(1.0)
3041
+ """
3042
+
3043
+ REQUIREDSEQUENCES = (wland_fluxes.PQ, wland_fluxes.FQS)
3044
+ UPDATEDSEQUENCES = (wland_states.HQ,)
3045
+
3046
+ @staticmethod
3047
+ def __call__(model: modeltools.Model) -> None:
3048
+ flu = model.sequences.fluxes.fastaccess
3049
+ old = model.sequences.states.fastaccess_old
3050
+ new = model.sequences.states.fastaccess_new
3051
+ new.hq = old.hq + (flu.pq - flu.fqs)
3052
+
3053
+
3054
+ class Update_HS_V1(modeltools.Method):
3055
+ r"""Update the surface water level.
3056
+
3057
+ Basic equation:
3058
+ :math:`\frac{dHS}{dt} =
3059
+ PS - ES + FXS + \frac{ALR \cdot FQS + AGR \cdot FGS - RH}{ASR}`
3060
+
3061
+ Example:
3062
+
3063
+ >>> from hydpy.models.wland import *
3064
+ >>> parameterstep()
3065
+ >>> derived.alr(0.8)
3066
+ >>> derived.asr(0.2)
3067
+ >>> derived.agr(0.8)
3068
+ >>> states.hs.old = 2.0
3069
+ >>> fluxes.fxs = 3.0
3070
+ >>> fluxes.ps = 4.0
3071
+ >>> fluxes.es = 5.0
3072
+ >>> fluxes.fgs = 6.0
3073
+ >>> fluxes.fqs = 7.0
3074
+ >>> fluxes.rh = 8.0
3075
+ >>> model.update_hs_v1()
3076
+ >>> states.hs
3077
+ hs(16.0)
3078
+ """
3079
+
3080
+ DERIVEDPARAMETERS = (wland_derived.ALR, wland_derived.ASR, wland_derived.AGR)
3081
+ REQUIREDSEQUENCES = (
3082
+ wland_fluxes.FXS,
3083
+ wland_fluxes.PS,
3084
+ wland_fluxes.ES,
3085
+ wland_fluxes.FGS,
3086
+ wland_fluxes.FQS,
3087
+ wland_fluxes.RH,
3088
+ )
3089
+ UPDATEDSEQUENCES = (wland_states.HS,)
3090
+
3091
+ @staticmethod
3092
+ def __call__(model: modeltools.Model) -> None:
3093
+ der = model.parameters.derived.fastaccess
3094
+ flu = model.sequences.fluxes.fastaccess
3095
+ old = model.sequences.states.fastaccess_old
3096
+ new = model.sequences.states.fastaccess_new
3097
+ new.hs = (
3098
+ old.hs
3099
+ + (flu.fxs + flu.ps - flu.es)
3100
+ + (der.alr * flu.fqs + der.agr * flu.fgs - flu.rh) / der.asr
3101
+ )
3102
+
3103
+
3104
+ class Calc_R_V1(modeltools.Method):
3105
+ r"""Calculate the runoff in m³/s.
3106
+
3107
+ Basic equation:
3108
+ :math:`R = QF \cdot RH`
3109
+
3110
+ Example:
3111
+
3112
+ >>> from hydpy.models.wland import *
3113
+ >>> parameterstep()
3114
+ >>> derived.qf(2.0)
3115
+ >>> fluxes.rh = 3.0
3116
+ >>> model.calc_r_v1()
3117
+ >>> fluxes.r
3118
+ r(6.0)
3119
+ """
3120
+
3121
+ DERIVEDPARAMETERS = (wland_derived.QF,)
3122
+ REQUIREDSEQUENCES = (wland_fluxes.RH,)
3123
+ RESULTSEQUENCES = (wland_fluxes.R,)
3124
+
3125
+ @staticmethod
3126
+ def __call__(model: modeltools.Model) -> None:
3127
+ der = model.parameters.derived.fastaccess
3128
+ flu = model.sequences.fluxes.fastaccess
3129
+ flu.r = der.qf * flu.rh
3130
+
3131
+
3132
+ class Pass_R_V1(modeltools.Method):
3133
+ r"""Update the outlet link sequence.
3134
+
3135
+ Basic equation:
3136
+ :math:`Q = R`
3137
+ """
3138
+
3139
+ REQUIREDSEQUENCES = (wland_fluxes.R,)
3140
+ RESULTSEQUENCES = (wland_outlets.Q,)
3141
+
3142
+ @staticmethod
3143
+ def __call__(model: modeltools.Model) -> None:
3144
+ flu = model.sequences.fluxes.fastaccess
3145
+ out = model.sequences.outlets.fastaccess
3146
+ out.q[0] += flu.r
3147
+
3148
+
3149
+ class Get_Temperature_V1(modeltools.Method):
3150
+ """Get the current subbasin-wide air temperature value (that applies to all
3151
+ hydrological response units so that the given index does not matter).
3152
+
3153
+ Example:
3154
+
3155
+ >>> from hydpy.models.wland import *
3156
+ >>> parameterstep()
3157
+ >>> inputs.t = 2.0
3158
+ >>> model.get_temperature_v1(0)
3159
+ 2.0
3160
+ >>> model.get_temperature_v1(1)
3161
+ 2.0
3162
+ """
3163
+
3164
+ REQUIREDSEQUENCES = (wland_inputs.T,)
3165
+
3166
+ @staticmethod
3167
+ def __call__(model: modeltools.Model, s: int) -> float:
3168
+ inp = model.sequences.inputs.fastaccess
3169
+
3170
+ return inp.t
3171
+
3172
+
3173
+ class Get_MeanTemperature_V1(modeltools.Method):
3174
+ """Get the current subbasin-wide air temperature value.
3175
+
3176
+ Example:
3177
+
3178
+ >>> from hydpy.models.wland import *
3179
+ >>> parameterstep()
3180
+ >>> inputs.t = 2.0
3181
+ >>> from hydpy import round_
3182
+ >>> round_(model.get_meantemperature_v1())
3183
+ 2.0
3184
+ """
3185
+
3186
+ REQUIREDSEQUENCES = (wland_inputs.T,)
3187
+
3188
+ @staticmethod
3189
+ def __call__(model: modeltools.Model) -> float:
3190
+ inp = model.sequences.inputs.fastaccess
3191
+
3192
+ return inp.t
3193
+
3194
+
3195
+ class Get_Precipitation_V1(modeltools.Method):
3196
+ """Get the current subbasin-wide precipitation value (that applies to all
3197
+ hydrological response units so that the given index does not matter).
3198
+
3199
+ Example:
3200
+
3201
+ >>> from hydpy.models.wland import *
3202
+ >>> parameterstep()
3203
+ >>> nu(2)
3204
+ >>> fluxes.pc = 2.0
3205
+ >>> model.get_precipitation_v1(0)
3206
+ 2.0
3207
+ >>> model.get_precipitation_v1(1)
3208
+ 2.0
3209
+ """
3210
+
3211
+ REQUIREDSEQUENCES = (wland_fluxes.PC,)
3212
+
3213
+ @staticmethod
3214
+ def __call__(model: modeltools.Model, s: int) -> float:
3215
+ flu = model.sequences.fluxes.fastaccess
3216
+
3217
+ return flu.pc
3218
+
3219
+
3220
+ class Get_SnowCover_V1(modeltools.Method):
3221
+ """Get the selected response unit's current snow cover degree.
3222
+
3223
+ Example:
3224
+
3225
+ Each response unit with a non-zero amount of snow counts as completely covered:
3226
+
3227
+ >>> from hydpy.models.wland import *
3228
+ >>> parameterstep()
3229
+ >>> nu(2)
3230
+ >>> states.sp = 0.0, 2.0
3231
+ >>> model.get_snowcover_v1(0)
3232
+ 0.0
3233
+ >>> model.get_snowcover_v1(1)
3234
+ 1.0
3235
+ """
3236
+
3237
+ REQUIREDSEQUENCES = (wland_states.SP,)
3238
+
3239
+ @staticmethod
3240
+ def __call__(model: modeltools.Model, k: int) -> float:
3241
+ sta = model.sequences.states.fastaccess
3242
+
3243
+ if sta.sp[k] > 0.0:
3244
+ return 1.0
3245
+ return 0.0
3246
+
3247
+
3248
+ class PegasusDGEq(roottools.Pegasus):
3249
+ """Pegasus iterator for finding the equilibrium groundwater depth."""
3250
+
3251
+ METHODS = (Return_ErrorDV_V1,)
3252
+
3253
+
3254
+ class QuadDVEq_V1(quadtools.Quad):
3255
+ """Adaptive quadrature method for integrating the equilibrium storage deficit
3256
+ of the vadose zone."""
3257
+
3258
+ METHODS = (Return_DVH_V1,)
3259
+
3260
+
3261
+ class QuadDVEq_V2(quadtools.Quad):
3262
+ """Adaptive quadrature method for integrating the equilibrium storage deficit
3263
+ of the vadose zone."""
3264
+
3265
+ METHODS = (Return_DVH_V2,)
3266
+
3267
+
3268
+ class Model(modeltools.ELSModel):
3269
+ """|wland.DOCNAME.complete|"""
3270
+
3271
+ DOCNAME = modeltools.DocName(short="W")
3272
+ __HYDPY_ROOTMODEL__ = None
3273
+
3274
+ SOLVERPARAMETERS = (
3275
+ wland_solver.AbsErrorMax,
3276
+ wland_solver.RelErrorMax,
3277
+ wland_solver.RelDTMin,
3278
+ wland_solver.RelDTMax,
3279
+ )
3280
+ SOLVERSEQUENCES = ()
3281
+ INLET_METHODS = (Calc_PE_PET_V1, Calc_FR_V1, Calc_PM_V1)
3282
+ RECEIVER_METHODS = (Pick_HS_V1,)
3283
+ INTERFACE_METHODS = (
3284
+ Get_Temperature_V1,
3285
+ Get_MeanTemperature_V1,
3286
+ Get_Precipitation_V1,
3287
+ Get_SnowCover_V1,
3288
+ )
3289
+ ADD_METHODS = (
3290
+ Calc_PE_PET_PETModel_V1,
3291
+ Calc_PE_PET_PETModel_V2,
3292
+ Return_ErrorDV_V1,
3293
+ Return_DVH_V1,
3294
+ Return_DVH_V2,
3295
+ )
3296
+ PART_ODE_METHODS = (
3297
+ Calc_FXS_V1,
3298
+ Calc_FXG_V1,
3299
+ Calc_PC_V1,
3300
+ Calc_TF_V1,
3301
+ Calc_EI_V1,
3302
+ Calc_SF_V1,
3303
+ Calc_RF_V1,
3304
+ Calc_AM_V1,
3305
+ Calc_PS_V1,
3306
+ Calc_WE_W_V1,
3307
+ Calc_PVE_PV_V1,
3308
+ Calc_PQ_V1,
3309
+ Calc_BetaE_Beta_V1,
3310
+ Calc_ETVE_ETV_V1,
3311
+ Calc_ES_V1,
3312
+ Calc_FQS_V1,
3313
+ Calc_FGSE_V1,
3314
+ Calc_FGS_V1,
3315
+ Calc_RH_V1,
3316
+ Calc_DVEq_V1,
3317
+ Calc_DVEq_V2,
3318
+ Calc_DVEq_V3,
3319
+ Calc_DVEq_V4,
3320
+ Calc_DGEq_V1,
3321
+ Calc_GF_V1,
3322
+ Calc_GR_V1,
3323
+ Calc_CDG_V1,
3324
+ Calc_CDG_V2,
3325
+ )
3326
+ FULL_ODE_METHODS = (
3327
+ Update_IC_V1,
3328
+ Update_SP_V1,
3329
+ Update_DVE_V1,
3330
+ Update_DV_V1,
3331
+ Update_HGE_V1,
3332
+ Update_DG_V1,
3333
+ Update_HQ_V1,
3334
+ Update_HS_V1,
3335
+ )
3336
+ OUTLET_METHODS = (Calc_ET_V1, Calc_R_V1, Pass_R_V1)
3337
+ SENDER_METHODS = ()
3338
+ SUBMODELINTERFACES = (
3339
+ petinterfaces.PETModel_V1,
3340
+ petinterfaces.PETModel_V2,
3341
+ dischargeinterfaces.DischargeModel_V2,
3342
+ stateinterfaces.WaterLevelModel_V1,
3343
+ )
3344
+ SUBMODELS = (PegasusDGEq, QuadDVEq_V1, QuadDVEq_V2)
3345
+
3346
+ petmodel = modeltools.SubmodelProperty(
3347
+ petinterfaces.PETModel_V1, petinterfaces.PETModel_V2
3348
+ )
3349
+ petmodel_is_mainmodel = modeltools.SubmodelIsMainmodelProperty()
3350
+ petmodel_typeid = modeltools.SubmodelTypeIDProperty()
3351
+
3352
+ dischargemodel = modeltools.SubmodelProperty(dischargeinterfaces.DischargeModel_V2)
3353
+ dischargemodel_is_mainmodel = modeltools.SubmodelIsMainmodelProperty()
3354
+ dischargemodel_typeid = modeltools.SubmodelTypeIDProperty()
3355
+
3356
+ waterlevelmodel = modeltools.SubmodelProperty(stateinterfaces.WaterLevelModel_V1)
3357
+ waterlevelmodel_is_mainmodel = modeltools.SubmodelIsMainmodelProperty()
3358
+ waterlevelmodel_typeid = modeltools.SubmodelTypeIDProperty()
3359
+
3360
+
3361
+ class BaseModel(modeltools.ELSModel):
3362
+ """Base model for |wland_wag| and |wland_gd|."""
3363
+
3364
+ def check_waterbalance(self, initial_conditions: ConditionsModel) -> float:
3365
+ r"""Determine the water balance error of the previous simulation run in mm.
3366
+
3367
+ Method |BaseModel.check_waterbalance| calculates the balance error as follows:
3368
+
3369
+ .. math::
3370
+ Error = \Sigma In - \Sigma Out + \Sigma \Delta H -
3371
+ \Delta Vol_{basin} - \Delta Vol_{hru}
3372
+ \\ \\
3373
+ \Sigma In = \sum_{t=t_0}^{t_1} PC_t + FXG_t + FXS_t
3374
+ \\
3375
+ \Sigma Out = \sum_{t=t_0}^{t_1} ET_t + RH_t
3376
+ \\
3377
+ \Sigma \Delta H= ASR \cdot \sum_{t=t_0}^{t_1} DHS_t
3378
+ \\
3379
+ \Delta Vol_{basin} =
3380
+ ALR \cdot f_{\Delta}(HQ)
3381
+ + AGRE \cdot \big( ThetaS \cdot f_{\Delta}(HGE) - f_{\Delta}(DV\!E) \big)
3382
+ - AGR \cdot f_{\Delta}(DV)
3383
+ + ASR \cdot f_{\Delta}(HS)
3384
+ \\
3385
+ \Delta Vol_{hru} = \sum_{k=1}^{NUL} AUR^k \cdot \big(
3386
+ f_{\Delta}(IC^k) + f_{\Delta}(SP)
3387
+ \big)
3388
+ \\ \\
3389
+ f_{\Delta}(x) = x_{t1} - x_{t0}
3390
+
3391
+ The returned error should always be in scale with numerical precision so that
3392
+ it does not affect the simulation results in any relevant manner.
3393
+
3394
+ Pick the required initial conditions before starting the simulation via
3395
+ property |Sequences.conditions|. See the integration tests of the application
3396
+ model |wland_wag| for some examples.
3397
+ """
3398
+ control = self.parameters.control
3399
+ derived = self.parameters.derived
3400
+ inputs = self.sequences.inputs
3401
+ factors = self.sequences.factors
3402
+ fluxes = self.sequences.fluxes
3403
+ last = self.sequences.states
3404
+ first = initial_conditions["model"]["states"]
3405
+ if derived.nug:
3406
+ delta_dv = (last.dv - first["dv"]) * derived.agr
3407
+ else:
3408
+ delta_dv = 0.0
3409
+ if derived.nuge:
3410
+ delta_dve = (last.dve - first["dve"]) * derived.agre
3411
+ delta_hge = (last.hge - first["hge"]) * derived.agre * control.thetas
3412
+ else:
3413
+ delta_dve = 0.0
3414
+ delta_hge = 0.0
3415
+ return (
3416
+ sum(fluxes.pc.series)
3417
+ + sum(inputs.fxg.series)
3418
+ + sum(inputs.fxs.series)
3419
+ - sum(fluxes.et.series)
3420
+ - sum(fluxes.rh.series)
3421
+ + sum(factors.dhs.series) * derived.asr
3422
+ - sum((last.ic - first["ic"])[:-1] * control.aur[:-1])
3423
+ - sum((last.sp - first["sp"])[:-1] * control.aur[:-1])
3424
+ + delta_dve
3425
+ + delta_dv
3426
+ - (last.hq - first["hq"]) * derived.alr
3427
+ - delta_hge
3428
+ - (last.hs - first["hs"]) * derived.asr
3429
+ )
3430
+
3431
+
3432
+ class Main_PETModel_V1(modeltools.ELSModel):
3433
+ """Base class for |wland.DOCNAME.long| models that use submodels that comply with
3434
+ the |PETModel_V1| interface."""
3435
+
3436
+ petmodel: modeltools.SubmodelProperty
3437
+ petmodel_is_mainmodel = modeltools.SubmodelIsMainmodelProperty()
3438
+ petmodel_typeid = modeltools.SubmodelTypeIDProperty()
3439
+
3440
+ @importtools.prepare_submodel(
3441
+ "petmodel",
3442
+ petinterfaces.PETModel_V1,
3443
+ petinterfaces.PETModel_V1.prepare_nmbzones,
3444
+ petinterfaces.PETModel_V1.prepare_subareas,
3445
+ petinterfaces.PETModel_V1.prepare_zonetypes,
3446
+ landtype_constants=wland_constants.LANDUSE_CONSTANTS,
3447
+ landtype_refindices=wland_control.LT,
3448
+ refweights=wland_control.AUR,
3449
+ )
3450
+ def add_petmodel_v1(
3451
+ self,
3452
+ petmodel: petinterfaces.PETModel_V1,
3453
+ /,
3454
+ *,
3455
+ refresh: bool, # pylint: disable=unused-argument
3456
+ ) -> None:
3457
+ """Initialise the given `petmodel` that follows the |PETModel_V1| interface.
3458
+
3459
+ >>> from hydpy.models.wland_wag import *
3460
+ >>> parameterstep()
3461
+ >>> nu(3)
3462
+ >>> at(10.0)
3463
+ >>> aur(0.5, 0.3, 0.2)
3464
+ >>> lt(FIELD, TREES, WATER)
3465
+ >>> with model.add_petmodel_v1("evap_ret_tw2002"):
3466
+ ... nmbhru
3467
+ ... hruarea
3468
+ ... evapotranspirationfactor(field=1.0, trees=2.0, water=1.5)
3469
+ ... for method, arguments in model.preparemethod2arguments.items():
3470
+ ... print(method, arguments[0][0], sep=": ")
3471
+ nmbhru(3)
3472
+ hruarea(5.0, 3.0, 2.0)
3473
+ prepare_nmbzones: 3
3474
+ prepare_zonetypes: [13 19 23]
3475
+ prepare_subareas: [5. 3. 2.]
3476
+
3477
+ >>> etf = model.petmodel.parameters.control.evapotranspirationfactor
3478
+ >>> etf
3479
+ evapotranspirationfactor(field=1.0, trees=2.0, water=1.5)
3480
+ >>> lt(TREES, FIELD, WATER)
3481
+ >>> etf
3482
+ evapotranspirationfactor(field=2.0, trees=1.0, water=1.5)
3483
+ >>> from hydpy import round_
3484
+ >>> round_(etf.average_values())
3485
+ 1.4
3486
+ """
3487
+ control = self.parameters.control
3488
+ petmodel.prepare_nmbzones(control.nu.value)
3489
+ petmodel.prepare_zonetypes(control.lt.values)
3490
+ petmodel.prepare_subareas(control.at.value * control.aur.values)
3491
+
3492
+
3493
+ class Main_PETModel_V2(modeltools.ELSModel):
3494
+ """Base class for |wland.DOCNAME.long| models that use submodels that comply with
3495
+ the |PETModel_V2| interface."""
3496
+
3497
+ petmodel: modeltools.SubmodelProperty
3498
+ petmodel_is_mainmodel = modeltools.SubmodelIsMainmodelProperty()
3499
+ petmodel_typeid = modeltools.SubmodelTypeIDProperty()
3500
+
3501
+ @importtools.prepare_submodel(
3502
+ "petmodel",
3503
+ petinterfaces.PETModel_V2,
3504
+ petinterfaces.PETModel_V2.prepare_nmbzones,
3505
+ petinterfaces.PETModel_V2.prepare_subareas,
3506
+ petinterfaces.PETModel_V2.prepare_zonetypes,
3507
+ petinterfaces.PETModel_V2.prepare_water,
3508
+ petinterfaces.PETModel_V2.prepare_interception,
3509
+ petinterfaces.PETModel_V2.prepare_soil,
3510
+ petinterfaces.PETModel_V2.prepare_plant,
3511
+ petinterfaces.PETModel_V2.prepare_tree,
3512
+ petinterfaces.PETModel_V2.prepare_leafareaindex,
3513
+ landtype_constants=wland_constants.LANDUSE_CONSTANTS,
3514
+ landtype_refindices=wland_control.LT,
3515
+ refweights=wland_control.AUR,
3516
+ )
3517
+ def add_petmodel_v2(
3518
+ self,
3519
+ petmodel: petinterfaces.PETModel_V2,
3520
+ /,
3521
+ *,
3522
+ refresh: bool, # pylint: disable=unused-argument
3523
+ ) -> None:
3524
+ """Initialise the given `petmodel` that follows the |PETModel_V2| interface.
3525
+
3526
+ >>> from hydpy import pub
3527
+ >>> pub.timegrids = "2000-01-01", "2001-01-01", "1d"
3528
+ >>> from hydpy.models.wland_wag import *
3529
+ >>> parameterstep()
3530
+ >>> nu(12)
3531
+ >>> at(10.0)
3532
+ >>> aur(0.006, 0.02, 0.034, 0.048, 0.062, 0.076,
3533
+ ... 0.09, 0.104, 0.118, 0.132, 0.146, 0.164)
3534
+ >>> lt(SEALED, FIELD, WINE, ORCHARD, SOIL, PASTURE,
3535
+ ... WETLAND, TREES, CONIFER, DECIDIOUS, MIXED, WATER)
3536
+ >>> lai(1.0)
3537
+ >>> lai.conifer_jan = 2.0
3538
+ >>> lai.pasture_dec = 3.0
3539
+ >>> with model.add_petmodel_v2("evap_pet_ambav1") as petmodel:
3540
+ ... nmbhru
3541
+ ... hrutype
3542
+ ... water
3543
+ ... interception
3544
+ ... soil
3545
+ ... plant
3546
+ ... my_lai = leafareaindex
3547
+ ... "my_lai", my_lai.field_jun, my_lai.conifer_jan, my_lai.pasture_dec
3548
+ ... petmodel.preparemethod2arguments["prepare_nmbzones"]
3549
+ ... petmodel.preparemethod2arguments["prepare_subareas"]
3550
+ ... groundalbedo(conifer=0.05, decidious=0.1, field=0.15, mixed=0.2,
3551
+ ... orchard=0.25, pasture=0.3, sealed=0.35, soil=0.4,
3552
+ ... trees=0.45, water=0.5, wetland=0.55, wine=0.6)
3553
+ ... for method, arguments in model.preparemethod2arguments.items():
3554
+ ... print(method, arguments[0][0], sep=": ") # doctest: +ELLIPSIS
3555
+ nmbhru(12)
3556
+ hrutype(SEALED, FIELD, WINE, ORCHARD, SOIL, PASTURE, WETLAND, TREES,
3557
+ CONIFER, DECIDIOUS, MIXED, WATER)
3558
+ water(conifer=False, decidious=False, field=False, mixed=False,
3559
+ orchard=False, pasture=False, sealed=False, soil=False,
3560
+ trees=False, water=True, wetland=False, wine=False)
3561
+ interception(conifer=True, decidious=True, field=True, mixed=True,
3562
+ orchard=True, pasture=True, sealed=True, soil=True,
3563
+ trees=True, water=False, wetland=True, wine=True)
3564
+ soil(conifer=True, decidious=True, field=True, mixed=True,
3565
+ orchard=True, pasture=True, sealed=False, soil=True, trees=True,
3566
+ water=False, wetland=True, wine=True)
3567
+ plant(conifer=True, decidious=True, field=True, mixed=True,
3568
+ orchard=True, pasture=True, sealed=False, soil=False,
3569
+ trees=True, water=False, wetland=True, wine=True)
3570
+ ('my_lai', 1.0, 2.0, 3.0)
3571
+ ((12,), {})
3572
+ ((array([0.06, 0.2 , 0.34, 0.48, 0.62, 0.76, 0.9 , 1.04, 1.18, 1.32, 1.46,
3573
+ 1.64]),), {})
3574
+ prepare_nmbzones: 12
3575
+ prepare_zonetypes: [12 13 14 15 16 17 18 19 20 21 22 23]
3576
+ prepare_subareas: [0.06 0.2 0.34 0.48 0.62 0.76 0.9 1.04 1.18 1.32 1.46 1.64]
3577
+ prepare_leafareaindex: [[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]
3578
+ ...
3579
+ prepare_water: [False False False False False False False False False False \
3580
+ False True]
3581
+ prepare_interception: [ True True True True True True True True True \
3582
+ True True False]
3583
+ prepare_soil: [False True True True True True True True True True \
3584
+ True False]
3585
+ prepare_plant: [False True True True False True True True True True \
3586
+ True False]
3587
+ prepare_tree: [False False False False False False False False True True \
3588
+ True False]
3589
+
3590
+ >>> assert model is model.petmodel.tempmodel
3591
+ >>> assert model is model.petmodel.precipmodel
3592
+ >>> assert model is model.petmodel.snowcovermodel
3593
+
3594
+ >>> ga = model.petmodel.parameters.control.groundalbedo
3595
+ >>> ga
3596
+ groundalbedo(conifer=0.05, decidious=0.1, field=0.15, mixed=0.2,
3597
+ orchard=0.25, pasture=0.3, sealed=0.35, soil=0.4,
3598
+ trees=0.45, water=0.5, wetland=0.55, wine=0.6)
3599
+ >>> lt(FIELD, SEALED, WINE, ORCHARD, SOIL, PASTURE,
3600
+ ... WETLAND, TREES, CONIFER, DECIDIOUS, MIXED, WATER)
3601
+ >>> ga
3602
+ groundalbedo(conifer=0.05, decidious=0.1, field=0.35, mixed=0.2,
3603
+ orchard=0.25, pasture=0.3, sealed=0.15, soil=0.4,
3604
+ trees=0.45, water=0.5, wetland=0.55, wine=0.6)
3605
+ >>> from hydpy import round_
3606
+ >>> round_(ga.average_values())
3607
+ 0.3117
3608
+ """
3609
+ control = self.parameters.control
3610
+ nu = control.nu.value
3611
+ lt = control.lt.values
3612
+
3613
+ petmodel.prepare_nmbzones(nu)
3614
+ petmodel.prepare_zonetypes(lt)
3615
+ petmodel.prepare_subareas(control.at.value * control.aur.values)
3616
+ petmodel.prepare_leafareaindex(control.lai.values)
3617
+ sel = numpy.full(nu, False, dtype=config.NP_BOOL)
3618
+ sel[-1] = True
3619
+ petmodel.prepare_water(sel)
3620
+ sel = ~sel
3621
+ petmodel.prepare_interception(sel)
3622
+ sel[lt == SEALED] = False
3623
+ petmodel.prepare_soil(sel)
3624
+ sel[lt == SOIL] = False
3625
+ petmodel.prepare_plant(sel)
3626
+ sel = numpy.full(nu, False, dtype=config.NP_BOOL)
3627
+ sel[lt == CONIFER] = True
3628
+ sel[lt == DECIDIOUS] = True
3629
+ sel[lt == MIXED] = True
3630
+ petmodel.prepare_tree(sel)
3631
+
3632
+
3633
+ class Main_DischargeModel_V2(modeltools.ELSModel):
3634
+ """Base class for |wland.DOCNAME.long| models that use submodels that comply with
3635
+ the |DischargeModel_V2| interface."""
3636
+
3637
+ dischargemodel: modeltools.SubmodelProperty
3638
+ dischargemodel_is_mainmodel = modeltools.SubmodelIsMainmodelProperty()
3639
+ dischargemodel_typeid = modeltools.SubmodelTypeIDProperty()
3640
+
3641
+ @importtools.prepare_submodel(
3642
+ "dischargemodel",
3643
+ dischargeinterfaces.DischargeModel_V2,
3644
+ dischargeinterfaces.DischargeModel_V2.prepare_channeldepth,
3645
+ dischargeinterfaces.DischargeModel_V2.prepare_tolerance,
3646
+ )
3647
+ def add_dischargemodel_v2(
3648
+ self,
3649
+ dischargemodel: dischargeinterfaces.DischargeModel_V2,
3650
+ /,
3651
+ *,
3652
+ refresh: bool, # pylint: disable=unused-argument
3653
+ ) -> None:
3654
+ """Initialise the given `dischargemodel` that follows the |DischargeModel_V2|
3655
+ interface.
3656
+
3657
+ Note the dependency on the derived parameter |CD|:
3658
+
3659
+ >>> from hydpy.models.wland_wag import *
3660
+ >>> parameterstep()
3661
+ >>> sh(10.0)
3662
+ >>> with model.add_dischargemodel_v2("wq_walrus", update=False):
3663
+ ... pass
3664
+ Traceback (most recent call last):
3665
+ ...
3666
+ hydpy.core.exceptiontools.AttributeNotReady: While trying to add a submodel \
3667
+ to the main model `wland_wag`, the following error occurred: While trying to \
3668
+ determine the missing value of the derived parameter `cd` of element `?`, the \
3669
+ following error occurred: While trying to subtract variable `gl` and `BL` instance \
3670
+ `bl(?)`, the following error occurred: For variable `bl`, no value has been defined \
3671
+ so far.
3672
+
3673
+ You can define its value manually for testing:
3674
+
3675
+ >>> derived.cd(2000.0)
3676
+ >>> with model.add_dischargemodel_v2("wq_walrus", update=False):
3677
+ ... channeldepth
3678
+ ... crestheighttolerance
3679
+ channeldepth(2.0)
3680
+ crestheighttolerance(0.01)
3681
+
3682
+ >>> model.dischargemodel.parameters.control.channeldepth
3683
+ channeldepth(2.0)
3684
+ >>> model.dischargemodel.parameters.control.crestheighttolerance
3685
+ crestheighttolerance(0.01)
3686
+
3687
+ However, |Main_DischargeModel_V2.add_dischargemodel_v2| updates the channel
3688
+ depth whenever possible to make the added submodel consistent with the main
3689
+ model's current control parameter values:
3690
+
3691
+ >>> gl(4.0)
3692
+ >>> bl(3.0)
3693
+ >>> with model.add_dischargemodel_v2("wq_walrus", update=False):
3694
+ ... channeldepth
3695
+ ... crestheighttolerance
3696
+ channeldepth(1.0)
3697
+ crestheighttolerance(0.01)
3698
+
3699
+ >>> derived.cd
3700
+ cd(1000.0)
3701
+ >>> model.dischargemodel.parameters.control.channeldepth
3702
+ channeldepth(1.0)
3703
+ >>> model.dischargemodel.parameters.control.crestheighttolerance
3704
+ crestheighttolerance(0.01)
3705
+ """
3706
+ cd = self.parameters.derived.cd
3707
+ try:
3708
+ cd.update()
3709
+ except exceptiontools.AttributeNotReady:
3710
+ if not exceptiontools.attrready(cd, "value"):
3711
+ objecttools.augment_excmessage(
3712
+ f"While trying to determine the missing value of the derived "
3713
+ f"parameter {objecttools.elementphrase(cd)}"
3714
+ )
3715
+ dischargemodel.prepare_channeldepth(cd.value / 1000.0)
3716
+ dischargemodel.prepare_tolerance(self.parameters.control.sh.value / 1000.0)
3717
+
3718
+
3719
+ class Main_WaterLevelModel_V1(modeltools.ELSModel):
3720
+ """Base class for |wland.DOCNAME.long| models that use submodels that comply with
3721
+ the |WaterLevelModel_V1| interface."""
3722
+
3723
+ waterlevelmodel: modeltools.SubmodelProperty
3724
+ waterlevelmodel_is_mainmodel = modeltools.SubmodelIsMainmodelProperty()
3725
+ waterlevelmodel_typeid = modeltools.SubmodelTypeIDProperty()
3726
+
3727
+ @importtools.prepare_submodel("waterlevelmodel", stateinterfaces.WaterLevelModel_V1)
3728
+ def add_waterlevelmodel_v1(
3729
+ self, waterlevelmodel: stateinterfaces.WaterLevelModel_V1, /, *, refresh: bool
3730
+ ) -> None:
3731
+ """Initialise the given `waterlevelmodel` that follows the |WaterLevelModel_V1|
3732
+ interface.
3733
+
3734
+ >>> from hydpy.models.wland_wag import *
3735
+ >>> parameterstep()
3736
+ >>> from hydpy.models import exch_waterlevel
3737
+ >>> with model.add_waterlevelmodel_v1(exch_waterlevel):
3738
+ ... pass
3739
+ >>> assert isinstance(model.waterlevelmodel, exch_waterlevel.Model)
3740
+ """
3741
+
3742
+
3743
+ class Sub_TempModel_V1(modeltools.ELSModel, tempinterfaces.TempModel_V1):
3744
+ """Base class for |wland.DOCNAME.long| models that comply with the |TempModel_V1|
3745
+ submodel interface."""
3746
+
3747
+
3748
+ class Sub_PrecipModel_V1(modeltools.ELSModel, precipinterfaces.PrecipModel_V1):
3749
+ """Base class for |wland.DOCNAME.long| models that comply with the |PrecipModel_V1|
3750
+ submodel interface."""
3751
+
3752
+
3753
+ class Sub_SnowCoverModel_V1(modeltools.ELSModel, stateinterfaces.SnowCoverModel_V1):
3754
+ """Base class for |wland.DOCNAME.long| models that comply with the
3755
+ |SnowCoverModel_V1| submodel interface."""