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.
- hydpy/__init__.py +275 -0
- hydpy/aliases.py +2554 -0
- hydpy/auxs/__init__.py +0 -0
- hydpy/auxs/anntools.py +1305 -0
- hydpy/auxs/armatools.py +883 -0
- hydpy/auxs/calibtools.py +3337 -0
- hydpy/auxs/interptools.py +1094 -0
- hydpy/auxs/iuhtools.py +543 -0
- hydpy/auxs/networktools.py +597 -0
- hydpy/auxs/ppolytools.py +809 -0
- hydpy/auxs/quadtools.py +61 -0
- hydpy/auxs/roottools.py +228 -0
- hydpy/auxs/smoothtools.py +273 -0
- hydpy/auxs/statstools.py +2125 -0
- hydpy/auxs/validtools.py +81 -0
- hydpy/conf/HydPyConfigBase.xsd +68637 -0
- hydpy/conf/HydPyConfigBase.xsdt +358 -0
- hydpy/conf/HydPyConfigMultipleRuns.xsd +25 -0
- hydpy/conf/HydPyConfigSingleRun.xsd +24 -0
- hydpy/conf/__init__.py +0 -0
- hydpy/conf/a_coefficients_explicit_lobatto_sequence.npy +0 -0
- hydpy/conf/support_points_for_smoothpar_logistic2.npy +0 -0
- hydpy/config.py +42 -0
- hydpy/core/__init__.py +0 -0
- hydpy/core/aliastools.py +214 -0
- hydpy/core/autodoctools.py +1947 -0
- hydpy/core/auxfiletools.py +1169 -0
- hydpy/core/devicetools.py +3810 -0
- hydpy/core/exceptiontools.py +269 -0
- hydpy/core/filetools.py +1985 -0
- hydpy/core/hydpytools.py +3089 -0
- hydpy/core/importtools.py +1398 -0
- hydpy/core/indextools.py +345 -0
- hydpy/core/itemtools.py +1849 -0
- hydpy/core/masktools.py +460 -0
- hydpy/core/modeltools.py +4868 -0
- hydpy/core/netcdftools.py +2683 -0
- hydpy/core/objecttools.py +2023 -0
- hydpy/core/optiontools.py +1045 -0
- hydpy/core/parametertools.py +4674 -0
- hydpy/core/printtools.py +222 -0
- hydpy/core/propertytools.py +643 -0
- hydpy/core/pubtools.py +254 -0
- hydpy/core/selectiontools.py +1571 -0
- hydpy/core/sequencetools.py +4476 -0
- hydpy/core/seriestools.py +339 -0
- hydpy/core/testtools.py +2483 -0
- hydpy/core/timetools.py +3567 -0
- hydpy/core/typingtools.py +333 -0
- hydpy/core/variabletools.py +2615 -0
- hydpy/cythons/__init__.py +24 -0
- hydpy/cythons/annutils.pxd +33 -0
- hydpy/cythons/annutils.pyi +25 -0
- hydpy/cythons/annutils.pyx +120 -0
- hydpy/cythons/autogen/__init__.py +0 -0
- hydpy/cythons/autogen/annutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/annutils.pxd +42 -0
- hydpy/cythons/autogen/annutils.pyx +129 -0
- hydpy/cythons/autogen/c_arma.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_arma.pxd +179 -0
- hydpy/cythons/autogen/c_arma.pyx +356 -0
- hydpy/cythons/autogen/c_arma_rimorido.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_arma_rimorido.pxd +179 -0
- hydpy/cythons/autogen/c_arma_rimorido.pyx +356 -0
- hydpy/cythons/autogen/c_conv.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_conv.pxd +198 -0
- hydpy/cythons/autogen/c_conv.pyx +491 -0
- hydpy/cythons/autogen/c_conv_idw.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_conv_idw.pxd +124 -0
- hydpy/cythons/autogen/c_conv_idw.pyx +264 -0
- hydpy/cythons/autogen/c_conv_idw_ed.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_conv_idw_ed.pxd +197 -0
- hydpy/cythons/autogen/c_conv_idw_ed.pyx +481 -0
- hydpy/cythons/autogen/c_conv_nn.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_conv_nn.pxd +120 -0
- hydpy/cythons/autogen/c_conv_nn.pyx +224 -0
- hydpy/cythons/autogen/c_dam.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam.pxd +805 -0
- hydpy/cythons/autogen/c_dam.pyx +1477 -0
- hydpy/cythons/autogen/c_dam_llake.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_llake.pxd +364 -0
- hydpy/cythons/autogen/c_dam_llake.pyx +705 -0
- hydpy/cythons/autogen/c_dam_lreservoir.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_lreservoir.pxd +365 -0
- hydpy/cythons/autogen/c_dam_lreservoir.pyx +708 -0
- hydpy/cythons/autogen/c_dam_lretention.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_lretention.pxd +340 -0
- hydpy/cythons/autogen/c_dam_lretention.pyx +625 -0
- hydpy/cythons/autogen/c_dam_pump.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_pump.pxd +402 -0
- hydpy/cythons/autogen/c_dam_pump.pyx +724 -0
- hydpy/cythons/autogen/c_dam_pump_sluice.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_pump_sluice.pxd +452 -0
- hydpy/cythons/autogen/c_dam_pump_sluice.pyx +829 -0
- hydpy/cythons/autogen/c_dam_sluice.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_sluice.pxd +404 -0
- hydpy/cythons/autogen/c_dam_sluice.pyx +726 -0
- hydpy/cythons/autogen/c_dam_v001.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_v001.pxd +452 -0
- hydpy/cythons/autogen/c_dam_v001.pyx +816 -0
- hydpy/cythons/autogen/c_dam_v002.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_v002.pxd +394 -0
- hydpy/cythons/autogen/c_dam_v002.pyx +703 -0
- hydpy/cythons/autogen/c_dam_v003.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_v003.pxd +417 -0
- hydpy/cythons/autogen/c_dam_v003.pyx +744 -0
- hydpy/cythons/autogen/c_dam_v004.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_v004.pxd +486 -0
- hydpy/cythons/autogen/c_dam_v004.pyx +891 -0
- hydpy/cythons/autogen/c_dam_v005.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dam_v005.pxd +524 -0
- hydpy/cythons/autogen/c_dam_v005.pyx +928 -0
- hydpy/cythons/autogen/c_dummy.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dummy.pxd +151 -0
- hydpy/cythons/autogen/c_dummy.pyx +263 -0
- hydpy/cythons/autogen/c_dummy_interceptedwater.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dummy_interceptedwater.pxd +69 -0
- hydpy/cythons/autogen/c_dummy_interceptedwater.pyx +104 -0
- hydpy/cythons/autogen/c_dummy_node2node.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dummy_node2node.pxd +89 -0
- hydpy/cythons/autogen/c_dummy_node2node.pyx +148 -0
- hydpy/cythons/autogen/c_dummy_snowalbedo.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dummy_snowalbedo.pxd +69 -0
- hydpy/cythons/autogen/c_dummy_snowalbedo.pyx +104 -0
- hydpy/cythons/autogen/c_dummy_snowcover.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dummy_snowcover.pxd +69 -0
- hydpy/cythons/autogen/c_dummy_snowcover.pyx +104 -0
- hydpy/cythons/autogen/c_dummy_snowycanopy.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dummy_snowycanopy.pxd +69 -0
- hydpy/cythons/autogen/c_dummy_snowycanopy.pyx +104 -0
- hydpy/cythons/autogen/c_dummy_soilwater.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_dummy_soilwater.pxd +69 -0
- hydpy/cythons/autogen/c_dummy_soilwater.pyx +104 -0
- hydpy/cythons/autogen/c_evap.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap.pxd +1029 -0
- hydpy/cythons/autogen/c_evap.pyx +2601 -0
- hydpy/cythons/autogen/c_evap_aet_hbv96.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_aet_hbv96.pxd +227 -0
- hydpy/cythons/autogen/c_evap_aet_hbv96.pyx +584 -0
- hydpy/cythons/autogen/c_evap_aet_minhas.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_aet_minhas.pxd +193 -0
- hydpy/cythons/autogen/c_evap_aet_minhas.pyx +478 -0
- hydpy/cythons/autogen/c_evap_aet_morsim.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_aet_morsim.pxd +681 -0
- hydpy/cythons/autogen/c_evap_aet_morsim.pyx +1642 -0
- hydpy/cythons/autogen/c_evap_pet_ambav1.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_pet_ambav1.pxd +532 -0
- hydpy/cythons/autogen/c_evap_pet_ambav1.pyx +1296 -0
- hydpy/cythons/autogen/c_evap_pet_hbv96.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_pet_hbv96.pxd +179 -0
- hydpy/cythons/autogen/c_evap_pet_hbv96.pyx +328 -0
- hydpy/cythons/autogen/c_evap_pet_m.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_pet_m.pxd +124 -0
- hydpy/cythons/autogen/c_evap_pet_m.pyx +214 -0
- hydpy/cythons/autogen/c_evap_pet_mlc.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_pet_mlc.pxd +126 -0
- hydpy/cythons/autogen/c_evap_pet_mlc.pyx +214 -0
- hydpy/cythons/autogen/c_evap_ret_fao56.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_ret_fao56.pxd +305 -0
- hydpy/cythons/autogen/c_evap_ret_fao56.pyx +624 -0
- hydpy/cythons/autogen/c_evap_ret_io.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_ret_io.pxd +112 -0
- hydpy/cythons/autogen/c_evap_ret_io.pyx +176 -0
- hydpy/cythons/autogen/c_evap_ret_tw2002.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_evap_ret_tw2002.pxd +139 -0
- hydpy/cythons/autogen/c_evap_ret_tw2002.pyx +273 -0
- hydpy/cythons/autogen/c_exch.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_exch.pxd +230 -0
- hydpy/cythons/autogen/c_exch.pyx +462 -0
- hydpy/cythons/autogen/c_exch_branch_hbv96.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_exch_branch_hbv96.pxd +134 -0
- hydpy/cythons/autogen/c_exch_branch_hbv96.pyx +255 -0
- hydpy/cythons/autogen/c_exch_waterlevel.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_exch_waterlevel.pxd +54 -0
- hydpy/cythons/autogen/c_exch_waterlevel.pyx +78 -0
- hydpy/cythons/autogen/c_exch_weir_hbv96.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_exch_weir_hbv96.pxd +156 -0
- hydpy/cythons/autogen/c_exch_weir_hbv96.pyx +282 -0
- hydpy/cythons/autogen/c_ga.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_ga.pxd +353 -0
- hydpy/cythons/autogen/c_ga.pyx +1204 -0
- hydpy/cythons/autogen/c_ga_garto.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_ga_garto.pxd +330 -0
- hydpy/cythons/autogen/c_ga_garto.pyx +1105 -0
- hydpy/cythons/autogen/c_ga_garto_submodel1.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_ga_garto_submodel1.pxd +236 -0
- hydpy/cythons/autogen/c_ga_garto_submodel1.pyx +944 -0
- hydpy/cythons/autogen/c_gland.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_gland.pxd +437 -0
- hydpy/cythons/autogen/c_gland.pyx +726 -0
- hydpy/cythons/autogen/c_gland_gr4.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_gland_gr4.pxd +382 -0
- hydpy/cythons/autogen/c_gland_gr4.pyx +605 -0
- hydpy/cythons/autogen/c_gland_gr5.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_gland_gr5.pxd +368 -0
- hydpy/cythons/autogen/c_gland_gr5.pyx +568 -0
- hydpy/cythons/autogen/c_gland_gr6.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_gland_gr6.pxd +420 -0
- hydpy/cythons/autogen/c_gland_gr6.pyx +673 -0
- hydpy/cythons/autogen/c_hland.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_hland.pxd +855 -0
- hydpy/cythons/autogen/c_hland.pyx +2486 -0
- hydpy/cythons/autogen/c_hland_96.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_hland_96.pxd +631 -0
- hydpy/cythons/autogen/c_hland_96.pyx +1724 -0
- hydpy/cythons/autogen/c_hland_96c.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_hland_96c.pxd +621 -0
- hydpy/cythons/autogen/c_hland_96c.pyx +1822 -0
- hydpy/cythons/autogen/c_hland_96p.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_hland_96p.pxd +683 -0
- hydpy/cythons/autogen/c_hland_96p.pyx +1911 -0
- hydpy/cythons/autogen/c_kinw.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_kinw.pxd +509 -0
- hydpy/cythons/autogen/c_kinw.pyx +965 -0
- hydpy/cythons/autogen/c_kinw_williams.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_kinw_williams.pxd +409 -0
- hydpy/cythons/autogen/c_kinw_williams.pyx +763 -0
- hydpy/cythons/autogen/c_kinw_williams_ext.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_kinw_williams_ext.pxd +220 -0
- hydpy/cythons/autogen/c_kinw_williams_ext.pyx +440 -0
- hydpy/cythons/autogen/c_lland.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_lland.pxd +1386 -0
- hydpy/cythons/autogen/c_lland.pyx +3679 -0
- hydpy/cythons/autogen/c_lland_dd.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_lland_dd.pxd +679 -0
- hydpy/cythons/autogen/c_lland_dd.pyx +1719 -0
- hydpy/cythons/autogen/c_lland_knauf.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_lland_knauf.pxd +1096 -0
- hydpy/cythons/autogen/c_lland_knauf.pyx +2784 -0
- hydpy/cythons/autogen/c_lland_knauf_ic.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_lland_knauf_ic.pxd +1369 -0
- hydpy/cythons/autogen/c_lland_knauf_ic.pyx +3625 -0
- hydpy/cythons/autogen/c_meteo.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo.pxd +469 -0
- hydpy/cythons/autogen/c_meteo.pyx +879 -0
- hydpy/cythons/autogen/c_meteo_clear_glob_io.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_clear_glob_io.pxd +75 -0
- hydpy/cythons/autogen/c_meteo_clear_glob_io.pyx +107 -0
- hydpy/cythons/autogen/c_meteo_glob_fao56.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_glob_fao56.pxd +209 -0
- hydpy/cythons/autogen/c_meteo_glob_fao56.pyx +339 -0
- hydpy/cythons/autogen/c_meteo_glob_io.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_glob_io.pxd +63 -0
- hydpy/cythons/autogen/c_meteo_glob_io.pyx +91 -0
- hydpy/cythons/autogen/c_meteo_glob_morsim.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_glob_morsim.pxd +289 -0
- hydpy/cythons/autogen/c_meteo_glob_morsim.pyx +527 -0
- hydpy/cythons/autogen/c_meteo_precip_io.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_precip_io.pxd +112 -0
- hydpy/cythons/autogen/c_meteo_precip_io.pyx +176 -0
- hydpy/cythons/autogen/c_meteo_psun_sun_glob_io.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_psun_sun_glob_io.pxd +87 -0
- hydpy/cythons/autogen/c_meteo_psun_sun_glob_io.pyx +123 -0
- hydpy/cythons/autogen/c_meteo_sun_fao56.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_sun_fao56.pxd +209 -0
- hydpy/cythons/autogen/c_meteo_sun_fao56.pyx +343 -0
- hydpy/cythons/autogen/c_meteo_sun_morsim.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_sun_morsim.pxd +286 -0
- hydpy/cythons/autogen/c_meteo_sun_morsim.pyx +519 -0
- hydpy/cythons/autogen/c_meteo_temp_io.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_meteo_temp_io.pxd +112 -0
- hydpy/cythons/autogen/c_meteo_temp_io.pyx +176 -0
- hydpy/cythons/autogen/c_musk.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_musk.pxd +282 -0
- hydpy/cythons/autogen/c_musk.pyx +605 -0
- hydpy/cythons/autogen/c_musk_classic.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_musk_classic.pxd +138 -0
- hydpy/cythons/autogen/c_musk_classic.pyx +226 -0
- hydpy/cythons/autogen/c_musk_mct.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_musk_mct.pxd +282 -0
- hydpy/cythons/autogen/c_musk_mct.pyx +609 -0
- hydpy/cythons/autogen/c_rconc.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_rconc.pxd +119 -0
- hydpy/cythons/autogen/c_rconc.pyx +174 -0
- hydpy/cythons/autogen/c_rconc_nash.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_rconc_nash.pxd +111 -0
- hydpy/cythons/autogen/c_rconc_nash.pyx +185 -0
- hydpy/cythons/autogen/c_rconc_uh.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_rconc_uh.pxd +92 -0
- hydpy/cythons/autogen/c_rconc_uh.pyx +125 -0
- hydpy/cythons/autogen/c_sw1d.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d.pxd +511 -0
- hydpy/cythons/autogen/c_sw1d.pyx +1263 -0
- hydpy/cythons/autogen/c_sw1d_channel.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_channel.pxd +119 -0
- hydpy/cythons/autogen/c_sw1d_channel.pyx +300 -0
- hydpy/cythons/autogen/c_sw1d_gate_out.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_gate_out.pxd +240 -0
- hydpy/cythons/autogen/c_sw1d_gate_out.pyx +476 -0
- hydpy/cythons/autogen/c_sw1d_lias.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_lias.pxd +320 -0
- hydpy/cythons/autogen/c_sw1d_lias.pyx +619 -0
- hydpy/cythons/autogen/c_sw1d_lias_sluice.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_lias_sluice.pxd +325 -0
- hydpy/cythons/autogen/c_sw1d_lias_sluice.pyx +644 -0
- hydpy/cythons/autogen/c_sw1d_network.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_network.pxd +90 -0
- hydpy/cythons/autogen/c_sw1d_network.pyx +246 -0
- hydpy/cythons/autogen/c_sw1d_pump.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_pump.pxd +256 -0
- hydpy/cythons/autogen/c_sw1d_pump.pyx +502 -0
- hydpy/cythons/autogen/c_sw1d_q_in.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_q_in.pxd +224 -0
- hydpy/cythons/autogen/c_sw1d_q_in.pyx +383 -0
- hydpy/cythons/autogen/c_sw1d_q_out.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_q_out.pxd +224 -0
- hydpy/cythons/autogen/c_sw1d_q_out.pyx +383 -0
- hydpy/cythons/autogen/c_sw1d_storage.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_storage.pxd +193 -0
- hydpy/cythons/autogen/c_sw1d_storage.pyx +349 -0
- hydpy/cythons/autogen/c_sw1d_weir_out.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_sw1d_weir_out.pxd +212 -0
- hydpy/cythons/autogen/c_sw1d_weir_out.pyx +404 -0
- hydpy/cythons/autogen/c_test.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_test.pxd +175 -0
- hydpy/cythons/autogen/c_test.pyx +348 -0
- hydpy/cythons/autogen/c_test_discontinous.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_test_discontinous.pxd +146 -0
- hydpy/cythons/autogen/c_test_discontinous.pyx +256 -0
- hydpy/cythons/autogen/c_test_stiff0d.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_test_stiff0d.pxd +146 -0
- hydpy/cythons/autogen/c_test_stiff0d.pyx +250 -0
- hydpy/cythons/autogen/c_test_stiff1d.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_test_stiff1d.pxd +145 -0
- hydpy/cythons/autogen/c_test_stiff1d.pyx +294 -0
- hydpy/cythons/autogen/c_whmod.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_whmod.pxd +482 -0
- hydpy/cythons/autogen/c_whmod.pyx +1156 -0
- hydpy/cythons/autogen/c_whmod_rural.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_whmod_rural.pxd +411 -0
- hydpy/cythons/autogen/c_whmod_rural.pyx +982 -0
- hydpy/cythons/autogen/c_whmod_urban.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_whmod_urban.pxd +482 -0
- hydpy/cythons/autogen/c_whmod_urban.pyx +1155 -0
- hydpy/cythons/autogen/c_wland.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_wland.pxd +842 -0
- hydpy/cythons/autogen/c_wland.pyx +1890 -0
- hydpy/cythons/autogen/c_wland_gd.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_wland_gd.pxd +829 -0
- hydpy/cythons/autogen/c_wland_gd.pyx +1847 -0
- hydpy/cythons/autogen/c_wland_wag.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_wland_wag.pxd +810 -0
- hydpy/cythons/autogen/c_wland_wag.pyx +1780 -0
- hydpy/cythons/autogen/c_wq.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_wq.pxd +275 -0
- hydpy/cythons/autogen/c_wq.pyx +652 -0
- hydpy/cythons/autogen/c_wq_trapeze.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_wq_trapeze.pxd +170 -0
- hydpy/cythons/autogen/c_wq_trapeze.pyx +400 -0
- hydpy/cythons/autogen/c_wq_trapeze_strickler.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_wq_trapeze_strickler.pxd +243 -0
- hydpy/cythons/autogen/c_wq_trapeze_strickler.pyx +578 -0
- hydpy/cythons/autogen/c_wq_walrus.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/c_wq_walrus.pxd +61 -0
- hydpy/cythons/autogen/c_wq_walrus.pyx +82 -0
- hydpy/cythons/autogen/configutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/configutils.pxd +17 -0
- hydpy/cythons/autogen/configutils.pyx +119 -0
- hydpy/cythons/autogen/interfaceutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/interfaceutils.pxd +31 -0
- hydpy/cythons/autogen/interfaceutils.pyx +82 -0
- hydpy/cythons/autogen/interputils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/interputils.pxd +42 -0
- hydpy/cythons/autogen/interputils.pyx +118 -0
- hydpy/cythons/autogen/masterinterface.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/masterinterface.pxd +153 -0
- hydpy/cythons/autogen/masterinterface.pyx +222 -0
- hydpy/cythons/autogen/pointerutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/pointerutils.pxd +31 -0
- hydpy/cythons/autogen/pointerutils.pyx +650 -0
- hydpy/cythons/autogen/ppolyutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/ppolyutils.pxd +35 -0
- hydpy/cythons/autogen/ppolyutils.pyx +59 -0
- hydpy/cythons/autogen/quadutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/quadutils.pxd +26 -0
- hydpy/cythons/autogen/quadutils.pyx +973 -0
- hydpy/cythons/autogen/rootutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/rootutils.pxd +28 -0
- hydpy/cythons/autogen/rootutils.pyx +109 -0
- hydpy/cythons/autogen/sequenceutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/sequenceutils.pxd +45 -0
- hydpy/cythons/autogen/sequenceutils.pyx +101 -0
- hydpy/cythons/autogen/smoothutils.cp313-win_amd64.pyd +0 -0
- hydpy/cythons/autogen/smoothutils.pxd +29 -0
- hydpy/cythons/autogen/smoothutils.pyx +833 -0
- hydpy/cythons/configutils.pxd +8 -0
- hydpy/cythons/configutils.pyi +5 -0
- hydpy/cythons/configutils.pyx +110 -0
- hydpy/cythons/interfaceutils.pxd +22 -0
- hydpy/cythons/interfaceutils.pyi +15 -0
- hydpy/cythons/interfaceutils.pyx +73 -0
- hydpy/cythons/interputils.pxd +33 -0
- hydpy/cythons/interputils.pyi +32 -0
- hydpy/cythons/interputils.pyx +109 -0
- hydpy/cythons/modelutils.py +2990 -0
- hydpy/cythons/pointerutils.pxd +22 -0
- hydpy/cythons/pointerutils.pyi +89 -0
- hydpy/cythons/pointerutils.pyx +641 -0
- hydpy/cythons/ppolyutils.pxd +26 -0
- hydpy/cythons/ppolyutils.pyi +21 -0
- hydpy/cythons/ppolyutils.pyx +50 -0
- hydpy/cythons/quadutils.pxd +17 -0
- hydpy/cythons/quadutils.pyi +13 -0
- hydpy/cythons/quadutils.pyx +964 -0
- hydpy/cythons/rootutils.pxd +19 -0
- hydpy/cythons/rootutils.pyi +21 -0
- hydpy/cythons/rootutils.pyx +100 -0
- hydpy/cythons/sequenceutils.pxd +36 -0
- hydpy/cythons/sequenceutils.pyi +7 -0
- hydpy/cythons/sequenceutils.pyx +92 -0
- hydpy/cythons/smoothutils.pxd +20 -0
- hydpy/cythons/smoothutils.pyi +15 -0
- hydpy/cythons/smoothutils.pyx +824 -0
- hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/land_dill_assl.py +13 -0
- hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/land_lahn_kalk.py +13 -0
- hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/land_lahn_leun.py +14 -0
- hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/land_lahn_marb.py +13 -0
- hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/stream_dill_assl_lahn_leun.py +5 -0
- hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/stream_lahn_leun_lahn_kalk.py +5 -0
- hydpy/data/HydPy-H-Lahn/conditions/init_1996_01_01_00_00_00/stream_lahn_marb_lahn_leun.py +5 -0
- hydpy/data/HydPy-H-Lahn/control/default/land.py +9 -0
- hydpy/data/HydPy-H-Lahn/control/default/land_dill_assl.py +57 -0
- hydpy/data/HydPy-H-Lahn/control/default/land_lahn_kalk.py +57 -0
- hydpy/data/HydPy-H-Lahn/control/default/land_lahn_leun.py +56 -0
- hydpy/data/HydPy-H-Lahn/control/default/land_lahn_marb.py +57 -0
- hydpy/data/HydPy-H-Lahn/control/default/stream_dill_assl_lahn_leun.py +7 -0
- hydpy/data/HydPy-H-Lahn/control/default/stream_lahn_leun_lahn_kalk.py +7 -0
- hydpy/data/HydPy-H-Lahn/control/default/stream_lahn_marb_lahn_leun.py +7 -0
- hydpy/data/HydPy-H-Lahn/multiple_runs.xml +309 -0
- hydpy/data/HydPy-H-Lahn/multiple_runs_alpha.xml +71 -0
- hydpy/data/HydPy-H-Lahn/network/default/headwaters.py +11 -0
- hydpy/data/HydPy-H-Lahn/network/default/nonheadwaters.py +11 -0
- hydpy/data/HydPy-H-Lahn/network/default/streams.py +8 -0
- hydpy/data/HydPy-H-Lahn/series/default/dill_assl_obs_q.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/evap_pet_hbv96_input_normalairtemperature.nc +0 -0
- hydpy/data/HydPy-H-Lahn/series/default/evap_pet_hbv96_input_normalevapotranspiration.nc +0 -0
- hydpy/data/HydPy-H-Lahn/series/default/hland_96_input_p.nc +0 -0
- hydpy/data/HydPy-H-Lahn/series/default/hland_96_input_t.nc +0 -0
- hydpy/data/HydPy-H-Lahn/series/default/lahn_kalk_obs_q.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/lahn_leun_obs_q.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/lahn_marb_obs_q.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_dill_assl_evap_pet_hbv96_input_normalairtemperature.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_dill_assl_evap_pet_hbv96_input_normalevapotranspiration.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_dill_assl_hland_96_input_p.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_dill_assl_hland_96_input_t.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_kalk_evap_pet_hbv96_input_normalairtemperature.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_kalk_evap_pet_hbv96_input_normalevapotranspiration.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_kalk_hland_96_input_p.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_kalk_hland_96_input_t.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_leun_evap_pet_hbv96_input_normalairtemperature.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_leun_evap_pet_hbv96_input_normalevapotranspiration.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_leun_hland_96_input_p.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_leun_hland_96_input_t.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_marb_evap_pet_hbv96_input_normalairtemperature.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_marb_evap_pet_hbv96_input_normalevapotranspiration.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_marb_hland_96_input_p.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/land_lahn_marb_hland_96_input_t.asc +11387 -0
- hydpy/data/HydPy-H-Lahn/series/default/obs_q.nc +0 -0
- hydpy/data/HydPy-H-Lahn/single_run.xml +152 -0
- hydpy/data/HydPy-H-Lahn/single_run.xmlt +143 -0
- hydpy/data/__init__.py +17 -0
- hydpy/docs/__init__.py +0 -0
- hydpy/docs/autofigs/__init__.py +0 -0
- hydpy/docs/bib/__init__.py +0 -0
- hydpy/docs/bib/refs.bib +566 -0
- hydpy/docs/combine_docversions.py +133 -0
- hydpy/docs/draw_model_sketches.py +1301 -0
- hydpy/docs/enable_autodoc.py +7 -0
- hydpy/docs/figs/HydPy-G-GR4.png +0 -0
- hydpy/docs/figs/HydPy-G-GR5.png +0 -0
- hydpy/docs/figs/HydPy-G-GR6.png +0 -0
- hydpy/docs/figs/HydPy-H-HBV96-COSERO.png +0 -0
- hydpy/docs/figs/HydPy-H-HBV96-PREVAH.png +0 -0
- hydpy/docs/figs/HydPy-H-HBV96.png +0 -0
- hydpy/docs/figs/HydPy-H-Lahn.png +0 -0
- hydpy/docs/figs/HydPy-KinW-Williams.png +0 -0
- hydpy/docs/figs/HydPy-L-DD.png +0 -0
- hydpy/docs/figs/HydPy-W-Wag.png +0 -0
- hydpy/docs/figs/HydPy_Logo.png +0 -0
- hydpy/docs/figs/HydPy_Logo_Text.png +0 -0
- hydpy/docs/figs/IDLE-editor.png +0 -0
- hydpy/docs/figs/IDLE-shell.png +0 -0
- hydpy/docs/figs/LAWA_river-basin-bumbers.png +0 -0
- hydpy/docs/figs/__init__.py +0 -0
- hydpy/docs/html_/__init__.py +0 -0
- hydpy/docs/polish_html.py +57 -0
- hydpy/docs/prepare.py +224 -0
- hydpy/docs/publish_docs.py +53 -0
- hydpy/docs/rst/HydPy-ARMA.rst +27 -0
- hydpy/docs/rst/HydPy-Conv.rst +22 -0
- hydpy/docs/rst/HydPy-Dam.rst +79 -0
- hydpy/docs/rst/HydPy-Dummy.rst +21 -0
- hydpy/docs/rst/HydPy-Evap.rst +26 -0
- hydpy/docs/rst/HydPy-Exch.rst +36 -0
- hydpy/docs/rst/HydPy-G.rst +40 -0
- hydpy/docs/rst/HydPy-GA.rst +34 -0
- hydpy/docs/rst/HydPy-H.rst +24 -0
- hydpy/docs/rst/HydPy-KinW.rst +32 -0
- hydpy/docs/rst/HydPy-L.rst +42 -0
- hydpy/docs/rst/HydPy-Meteo.rst +28 -0
- hydpy/docs/rst/HydPy-Musk.rst +21 -0
- hydpy/docs/rst/HydPy-Rconc.rst +17 -0
- hydpy/docs/rst/HydPy-SW1D.rst +49 -0
- hydpy/docs/rst/HydPy-Test.rst +19 -0
- hydpy/docs/rst/HydPy-W.rst +20 -0
- hydpy/docs/rst/HydPy-WHMod.rst +19 -0
- hydpy/docs/rst/HydPy-WQ.rst +20 -0
- hydpy/docs/rst/__init__.py +0 -0
- hydpy/docs/rst/additional_repositories.rst +40 -0
- hydpy/docs/rst/auxiliaries.rst +31 -0
- hydpy/docs/rst/continuous_integration.rst +75 -0
- hydpy/docs/rst/core.rst +75 -0
- hydpy/docs/rst/cythons.rst +47 -0
- hydpy/docs/rst/definitions.rst +506 -0
- hydpy/docs/rst/developer_guide.rst +54 -0
- hydpy/docs/rst/example_projects.rst +40 -0
- hydpy/docs/rst/execution.rst +22 -0
- hydpy/docs/rst/framework_tools.rst +56 -0
- hydpy/docs/rst/how_to_read_the_reference_manual.rst +156 -0
- hydpy/docs/rst/hydpydependencies.rst +55 -0
- hydpy/docs/rst/index.rst +125 -0
- hydpy/docs/rst/installation.rst +155 -0
- hydpy/docs/rst/model_families.rst +79 -0
- hydpy/docs/rst/model_overview.rst +291 -0
- hydpy/docs/rst/modelimports.rst +10 -0
- hydpy/docs/rst/options.rst +119 -0
- hydpy/docs/rst/programming_style.rst +572 -0
- hydpy/docs/rst/project_structure.rst +520 -0
- hydpy/docs/rst/quickstart.rst +304 -0
- hydpy/docs/rst/reference_manual.rst +29 -0
- hydpy/docs/rst/required_tools.rst +50 -0
- hydpy/docs/rst/simulation.rst +514 -0
- hydpy/docs/rst/submodel_interfaces.rst +32 -0
- hydpy/docs/rst/tests_and_documentation.rst +85 -0
- hydpy/docs/rst/user_guide.rst +38 -0
- hydpy/docs/rst/version_control.rst +116 -0
- hydpy/docs/rst/zbibliography.rst +8 -0
- hydpy/docs/sphinx/__init__.py +0 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/changes/frameset.html +11 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/changes/rstsource.html +15 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/changes/versionchanges.html +33 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/defindex.html +35 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/domainindex.html +56 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/genindex-single.html +63 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/genindex-split.html +41 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/genindex.html +76 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/globaltoc.html +11 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/layout.html +221 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/localtoc.html +15 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/opensearch.xml +13 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/page.html +13 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/relations.html +23 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/search.html +65 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/searchbox.html +21 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/searchfield.html +23 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/sourcelink.html +18 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/basic.css_t +925 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/doctools.js +156 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/documentation_options.js_t +13 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/file.png +0 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/language_data.js_t +26 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/minus.png +0 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/plus.png +0 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/searchtools.js +574 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/static/sphinx_highlight.js +154 -0
- hydpy/docs/sphinx/_themes/basic_hydpy/theme.conf +16 -0
- hydpy/docs/sphinx/_themes/classic_hydpy/layout.html +23 -0
- hydpy/docs/sphinx/_themes/classic_hydpy/static/classic.css_t +358 -0
- hydpy/docs/sphinx/_themes/classic_hydpy/static/sidebar.js_t +72 -0
- hydpy/docs/sphinx/_themes/classic_hydpy/theme.conf +32 -0
- hydpy/docs/sphinx/conf.py +398 -0
- hydpy/docs/sphinx/defaultlinks_extension.py +36 -0
- hydpy/docs/sphinx/integrationtest_extension.py +104 -0
- hydpy/docs/sphinx/projectstructure_extension.py +58 -0
- hydpy/docs/sphinx/submodelgraph_extension.py +53 -0
- hydpy/exe/__init__.py +0 -0
- hydpy/exe/commandtools.py +651 -0
- hydpy/exe/hyd.py +277 -0
- hydpy/exe/modelimports.py +41 -0
- hydpy/exe/replacetools.py +216 -0
- hydpy/exe/servertools.py +2348 -0
- hydpy/exe/xmltools.py +3280 -0
- hydpy/interfaces/__init__.py +0 -0
- hydpy/interfaces/aetinterfaces.py +94 -0
- hydpy/interfaces/dischargeinterfaces.py +45 -0
- hydpy/interfaces/petinterfaces.py +117 -0
- hydpy/interfaces/precipinterfaces.py +42 -0
- hydpy/interfaces/radiationinterfaces.py +79 -0
- hydpy/interfaces/rconcinterfaces.py +30 -0
- hydpy/interfaces/routinginterfaces.py +324 -0
- hydpy/interfaces/soilinterfaces.py +96 -0
- hydpy/interfaces/stateinterfaces.py +98 -0
- hydpy/interfaces/tempinterfaces.py +46 -0
- hydpy/models/__init__.py +0 -0
- hydpy/models/arma/__init__.py +14 -0
- hydpy/models/arma/arma_control.py +383 -0
- hydpy/models/arma/arma_derived.py +204 -0
- hydpy/models/arma/arma_fluxes.py +41 -0
- hydpy/models/arma/arma_inlets.py +11 -0
- hydpy/models/arma/arma_logs.py +19 -0
- hydpy/models/arma/arma_model.py +461 -0
- hydpy/models/arma/arma_outlets.py +11 -0
- hydpy/models/arma_rimorido.py +381 -0
- hydpy/models/conv/__init__.py +12 -0
- hydpy/models/conv/conv_control.py +303 -0
- hydpy/models/conv/conv_derived.py +271 -0
- hydpy/models/conv/conv_fluxes.py +54 -0
- hydpy/models/conv/conv_inlets.py +11 -0
- hydpy/models/conv/conv_model.py +687 -0
- hydpy/models/conv/conv_outlets.py +11 -0
- hydpy/models/conv_idw.py +120 -0
- hydpy/models/conv_idw_ed.py +184 -0
- hydpy/models/conv_nn.py +112 -0
- hydpy/models/dam/__init__.py +16 -0
- hydpy/models/dam/dam_aides.py +17 -0
- hydpy/models/dam/dam_control.py +346 -0
- hydpy/models/dam/dam_derived.py +559 -0
- hydpy/models/dam/dam_factors.py +46 -0
- hydpy/models/dam/dam_fluxes.py +179 -0
- hydpy/models/dam/dam_inlets.py +29 -0
- hydpy/models/dam/dam_logs.py +52 -0
- hydpy/models/dam/dam_model.py +5011 -0
- hydpy/models/dam/dam_outlets.py +23 -0
- hydpy/models/dam/dam_receivers.py +41 -0
- hydpy/models/dam/dam_senders.py +23 -0
- hydpy/models/dam/dam_solver.py +75 -0
- hydpy/models/dam/dam_states.py +11 -0
- hydpy/models/dam_llake.py +499 -0
- hydpy/models/dam_lreservoir.py +548 -0
- hydpy/models/dam_lretention.py +343 -0
- hydpy/models/dam_pump.py +278 -0
- hydpy/models/dam_pump_sluice.py +339 -0
- hydpy/models/dam_sluice.py +319 -0
- hydpy/models/dam_v001.py +1127 -0
- hydpy/models/dam_v002.py +381 -0
- hydpy/models/dam_v003.py +422 -0
- hydpy/models/dam_v004.py +665 -0
- hydpy/models/dam_v005.py +479 -0
- hydpy/models/dummy/__init__.py +15 -0
- hydpy/models/dummy/dummy_control.py +22 -0
- hydpy/models/dummy/dummy_fluxes.py +11 -0
- hydpy/models/dummy/dummy_inlets.py +11 -0
- hydpy/models/dummy/dummy_inputs.py +41 -0
- hydpy/models/dummy/dummy_model.py +196 -0
- hydpy/models/dummy/dummy_outlets.py +11 -0
- hydpy/models/dummy_interceptedwater.py +85 -0
- hydpy/models/dummy_node2node.py +83 -0
- hydpy/models/dummy_snowalbedo.py +84 -0
- hydpy/models/dummy_snowcover.py +84 -0
- hydpy/models/dummy_snowycanopy.py +86 -0
- hydpy/models/dummy_soilwater.py +85 -0
- hydpy/models/evap/__init__.py +13 -0
- hydpy/models/evap/evap_control.py +354 -0
- hydpy/models/evap/evap_derived.py +236 -0
- hydpy/models/evap/evap_factors.py +188 -0
- hydpy/models/evap/evap_fixed.py +68 -0
- hydpy/models/evap/evap_fluxes.py +150 -0
- hydpy/models/evap/evap_inputs.py +54 -0
- hydpy/models/evap/evap_logs.py +91 -0
- hydpy/models/evap/evap_masks.py +48 -0
- hydpy/models/evap/evap_model.py +9170 -0
- hydpy/models/evap/evap_parameters.py +149 -0
- hydpy/models/evap/evap_sequences.py +32 -0
- hydpy/models/evap/evap_states.py +18 -0
- hydpy/models/evap_aet_hbv96.py +372 -0
- hydpy/models/evap_aet_minhas.py +331 -0
- hydpy/models/evap_aet_morsim.py +627 -0
- hydpy/models/evap_pet_ambav1.py +483 -0
- hydpy/models/evap_pet_hbv96.py +147 -0
- hydpy/models/evap_pet_m.py +94 -0
- hydpy/models/evap_pet_mlc.py +107 -0
- hydpy/models/evap_ret_fao56.py +265 -0
- hydpy/models/evap_ret_io.py +74 -0
- hydpy/models/evap_ret_tw2002.py +165 -0
- hydpy/models/exch/__init__.py +14 -0
- hydpy/models/exch/exch_control.py +262 -0
- hydpy/models/exch/exch_derived.py +36 -0
- hydpy/models/exch/exch_factors.py +26 -0
- hydpy/models/exch/exch_fluxes.py +48 -0
- hydpy/models/exch/exch_inlets.py +11 -0
- hydpy/models/exch/exch_logs.py +12 -0
- hydpy/models/exch/exch_model.py +451 -0
- hydpy/models/exch/exch_outlets.py +17 -0
- hydpy/models/exch/exch_receivers.py +17 -0
- hydpy/models/exch_branch_hbv96.py +186 -0
- hydpy/models/exch_waterlevel.py +73 -0
- hydpy/models/exch_weir_hbv96.py +609 -0
- hydpy/models/ga/__init__.py +14 -0
- hydpy/models/ga/ga_aides.py +17 -0
- hydpy/models/ga/ga_control.py +208 -0
- hydpy/models/ga/ga_derived.py +77 -0
- hydpy/models/ga/ga_fluxes.py +83 -0
- hydpy/models/ga/ga_inputs.py +26 -0
- hydpy/models/ga/ga_logs.py +17 -0
- hydpy/models/ga/ga_model.py +2952 -0
- hydpy/models/ga/ga_states.py +87 -0
- hydpy/models/ga_garto.py +1001 -0
- hydpy/models/ga_garto_submodel1.py +79 -0
- hydpy/models/gland/__init__.py +14 -0
- hydpy/models/gland/gland_control.py +90 -0
- hydpy/models/gland/gland_derived.py +113 -0
- hydpy/models/gland/gland_fluxes.py +137 -0
- hydpy/models/gland/gland_inputs.py +12 -0
- hydpy/models/gland/gland_model.py +1439 -0
- hydpy/models/gland/gland_outlets.py +11 -0
- hydpy/models/gland/gland_states.py +90 -0
- hydpy/models/gland_gr4.py +501 -0
- hydpy/models/gland_gr5.py +463 -0
- hydpy/models/gland_gr6.py +487 -0
- hydpy/models/hland/__init__.py +20 -0
- hydpy/models/hland/hland_aides.py +19 -0
- hydpy/models/hland/hland_constants.py +37 -0
- hydpy/models/hland/hland_control.py +1530 -0
- hydpy/models/hland/hland_derived.py +683 -0
- hydpy/models/hland/hland_factors.py +57 -0
- hydpy/models/hland/hland_fixed.py +42 -0
- hydpy/models/hland/hland_fluxes.py +279 -0
- hydpy/models/hland/hland_inputs.py +19 -0
- hydpy/models/hland/hland_masks.py +107 -0
- hydpy/models/hland/hland_model.py +4664 -0
- hydpy/models/hland/hland_outlets.py +11 -0
- hydpy/models/hland/hland_parameters.py +227 -0
- hydpy/models/hland/hland_sequences.py +382 -0
- hydpy/models/hland/hland_states.py +236 -0
- hydpy/models/hland_96.py +1812 -0
- hydpy/models/hland_96c.py +1196 -0
- hydpy/models/hland_96p.py +1204 -0
- hydpy/models/kinw/__init__.py +18 -0
- hydpy/models/kinw/kinw_aides.py +306 -0
- hydpy/models/kinw/kinw_control.py +270 -0
- hydpy/models/kinw/kinw_derived.py +197 -0
- hydpy/models/kinw/kinw_fixed.py +33 -0
- hydpy/models/kinw/kinw_fluxes.py +37 -0
- hydpy/models/kinw/kinw_inlets.py +11 -0
- hydpy/models/kinw/kinw_model.py +3026 -0
- hydpy/models/kinw/kinw_outlets.py +11 -0
- hydpy/models/kinw/kinw_solver.py +45 -0
- hydpy/models/kinw/kinw_states.py +17 -0
- hydpy/models/kinw_williams.py +1299 -0
- hydpy/models/kinw_williams_ext.py +768 -0
- hydpy/models/lland/__init__.py +42 -0
- hydpy/models/lland/lland_aides.py +38 -0
- hydpy/models/lland/lland_constants.py +88 -0
- hydpy/models/lland/lland_control.py +1329 -0
- hydpy/models/lland/lland_derived.py +380 -0
- hydpy/models/lland/lland_factors.py +18 -0
- hydpy/models/lland/lland_fixed.py +128 -0
- hydpy/models/lland/lland_fluxes.py +626 -0
- hydpy/models/lland/lland_inlets.py +12 -0
- hydpy/models/lland/lland_inputs.py +33 -0
- hydpy/models/lland/lland_logs.py +17 -0
- hydpy/models/lland/lland_masks.py +212 -0
- hydpy/models/lland/lland_model.py +7690 -0
- hydpy/models/lland/lland_outlets.py +12 -0
- hydpy/models/lland/lland_parameters.py +195 -0
- hydpy/models/lland/lland_sequences.py +67 -0
- hydpy/models/lland/lland_states.py +280 -0
- hydpy/models/lland_dd.py +2270 -0
- hydpy/models/lland_knauf.py +2156 -0
- hydpy/models/lland_knauf_ic.py +1920 -0
- hydpy/models/meteo/__init__.py +12 -0
- hydpy/models/meteo/meteo_control.py +154 -0
- hydpy/models/meteo/meteo_derived.py +159 -0
- hydpy/models/meteo/meteo_factors.py +88 -0
- hydpy/models/meteo/meteo_fixed.py +19 -0
- hydpy/models/meteo/meteo_fluxes.py +46 -0
- hydpy/models/meteo/meteo_inputs.py +47 -0
- hydpy/models/meteo/meteo_logs.py +30 -0
- hydpy/models/meteo/meteo_model.py +2904 -0
- hydpy/models/meteo/meteo_parameters.py +14 -0
- hydpy/models/meteo/meteo_sequences.py +22 -0
- hydpy/models/meteo_clear_glob_io.py +77 -0
- hydpy/models/meteo_glob_fao56.py +217 -0
- hydpy/models/meteo_glob_io.py +68 -0
- hydpy/models/meteo_glob_morsim.py +444 -0
- hydpy/models/meteo_precip_io.py +76 -0
- hydpy/models/meteo_psun_sun_glob_io.py +83 -0
- hydpy/models/meteo_sun_fao56.py +188 -0
- hydpy/models/meteo_sun_morsim.py +466 -0
- hydpy/models/meteo_temp_io.py +76 -0
- hydpy/models/musk/__init__.py +15 -0
- hydpy/models/musk/musk_control.py +328 -0
- hydpy/models/musk/musk_derived.py +32 -0
- hydpy/models/musk/musk_factors.py +53 -0
- hydpy/models/musk/musk_fluxes.py +24 -0
- hydpy/models/musk/musk_inlets.py +11 -0
- hydpy/models/musk/musk_masks.py +15 -0
- hydpy/models/musk/musk_model.py +838 -0
- hydpy/models/musk/musk_outlets.py +11 -0
- hydpy/models/musk/musk_sequences.py +88 -0
- hydpy/models/musk/musk_solver.py +68 -0
- hydpy/models/musk/musk_states.py +64 -0
- hydpy/models/musk_classic.py +228 -0
- hydpy/models/musk_mct.py +1247 -0
- hydpy/models/rconc/__init__.py +12 -0
- hydpy/models/rconc/rconc_control.py +473 -0
- hydpy/models/rconc/rconc_derived.py +76 -0
- hydpy/models/rconc/rconc_fluxes.py +19 -0
- hydpy/models/rconc/rconc_logs.py +74 -0
- hydpy/models/rconc/rconc_model.py +260 -0
- hydpy/models/rconc/rconc_states.py +11 -0
- hydpy/models/rconc_nash.py +48 -0
- hydpy/models/rconc_uh.py +53 -0
- hydpy/models/sw1d/__init__.py +17 -0
- hydpy/models/sw1d/sw1d_control.py +356 -0
- hydpy/models/sw1d/sw1d_derived.py +85 -0
- hydpy/models/sw1d/sw1d_factors.py +78 -0
- hydpy/models/sw1d/sw1d_fixed.py +12 -0
- hydpy/models/sw1d/sw1d_fluxes.py +55 -0
- hydpy/models/sw1d/sw1d_inlets.py +17 -0
- hydpy/models/sw1d/sw1d_model.py +3385 -0
- hydpy/models/sw1d/sw1d_outlets.py +11 -0
- hydpy/models/sw1d/sw1d_receivers.py +11 -0
- hydpy/models/sw1d/sw1d_senders.py +11 -0
- hydpy/models/sw1d/sw1d_states.py +23 -0
- hydpy/models/sw1d_channel.py +2051 -0
- hydpy/models/sw1d_gate_out.py +599 -0
- hydpy/models/sw1d_lias.py +105 -0
- hydpy/models/sw1d_lias_sluice.py +531 -0
- hydpy/models/sw1d_network.py +1219 -0
- hydpy/models/sw1d_pump.py +448 -0
- hydpy/models/sw1d_q_in.py +79 -0
- hydpy/models/sw1d_q_out.py +81 -0
- hydpy/models/sw1d_storage.py +78 -0
- hydpy/models/sw1d_weir_out.py +75 -0
- hydpy/models/test/__init__.py +14 -0
- hydpy/models/test/test_control.py +28 -0
- hydpy/models/test/test_fluxes.py +17 -0
- hydpy/models/test/test_model.py +201 -0
- hydpy/models/test/test_solver.py +48 -0
- hydpy/models/test/test_states.py +17 -0
- hydpy/models/test_discontinous.py +46 -0
- hydpy/models/test_stiff0d.py +47 -0
- hydpy/models/test_stiff1d.py +42 -0
- hydpy/models/whmod/__init__.py +21 -0
- hydpy/models/whmod/whmod_constants.py +77 -0
- hydpy/models/whmod/whmod_control.py +333 -0
- hydpy/models/whmod/whmod_derived.py +210 -0
- hydpy/models/whmod/whmod_factors.py +9 -0
- hydpy/models/whmod/whmod_fluxes.py +105 -0
- hydpy/models/whmod/whmod_inputs.py +15 -0
- hydpy/models/whmod/whmod_masks.py +178 -0
- hydpy/models/whmod/whmod_model.py +2091 -0
- hydpy/models/whmod/whmod_parameters.py +155 -0
- hydpy/models/whmod/whmod_sequences.py +193 -0
- hydpy/models/whmod/whmod_states.py +73 -0
- hydpy/models/whmod_rural.py +794 -0
- hydpy/models/whmod_urban.py +1011 -0
- hydpy/models/wland/__init__.py +43 -0
- hydpy/models/wland/wland_aides.py +55 -0
- hydpy/models/wland/wland_constants.py +103 -0
- hydpy/models/wland/wland_control.py +508 -0
- hydpy/models/wland/wland_derived.py +330 -0
- hydpy/models/wland/wland_factors.py +11 -0
- hydpy/models/wland/wland_fixed.py +12 -0
- hydpy/models/wland/wland_fluxes.py +166 -0
- hydpy/models/wland/wland_inputs.py +33 -0
- hydpy/models/wland/wland_masks.py +54 -0
- hydpy/models/wland/wland_model.py +3755 -0
- hydpy/models/wland/wland_outlets.py +11 -0
- hydpy/models/wland/wland_parameters.py +214 -0
- hydpy/models/wland/wland_sequences.py +108 -0
- hydpy/models/wland/wland_solver.py +45 -0
- hydpy/models/wland/wland_states.py +56 -0
- hydpy/models/wland_gd.py +888 -0
- hydpy/models/wland_wag.py +1244 -0
- hydpy/models/wq/__init__.py +14 -0
- hydpy/models/wq/wq_control.py +117 -0
- hydpy/models/wq/wq_derived.py +182 -0
- hydpy/models/wq/wq_factors.py +79 -0
- hydpy/models/wq/wq_fluxes.py +17 -0
- hydpy/models/wq/wq_model.py +1889 -0
- hydpy/models/wq_trapeze.py +168 -0
- hydpy/models/wq_trapeze_strickler.py +101 -0
- hydpy/models/wq_walrus.py +57 -0
- hydpy/py.typed +0 -0
- hydpy/tests/.coveragerc +22 -0
- hydpy/tests/__init__.py +0 -0
- hydpy/tests/check_consistency.py +32 -0
- hydpy/tests/hydpydoctestcustomize.pth +1 -0
- hydpy/tests/hydpydoctestcustomize.py +15 -0
- hydpy/tests/iotesting/__init__.py +0 -0
- hydpy/tests/run_doctests.py +233 -0
- hydpy-6.2.dev1.data/scripts/hyd.py +277 -0
- hydpy-6.2.dev1.dist-info/LICENSE +165 -0
- hydpy-6.2.dev1.dist-info/METADATA +163 -0
- hydpy-6.2.dev1.dist-info/RECORD +890 -0
- hydpy-6.2.dev1.dist-info/WHEEL +5 -0
- hydpy-6.2.dev1.dist-info/licenses_hydpy_installer.txt +42 -0
- hydpy-6.2.dev1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,1530 @@
|
|
|
1
|
+
"""
|
|
2
|
+
.. _`issue 67`: https://github.com/hydpy-dev/hydpy/issues/67
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
# import...
|
|
6
|
+
# from standard library
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
import functools
|
|
9
|
+
import warnings
|
|
10
|
+
|
|
11
|
+
# from site-packages
|
|
12
|
+
import numpy
|
|
13
|
+
|
|
14
|
+
# ...from HydPy
|
|
15
|
+
from hydpy import config
|
|
16
|
+
from hydpy.core import exceptiontools
|
|
17
|
+
from hydpy.core import objecttools
|
|
18
|
+
from hydpy.core import parametertools
|
|
19
|
+
from hydpy.core.typingtools import *
|
|
20
|
+
|
|
21
|
+
# ...from hland
|
|
22
|
+
from hydpy.models.hland import hland_constants
|
|
23
|
+
from hydpy.models.hland import hland_fixed
|
|
24
|
+
from hydpy.models.hland import hland_parameters
|
|
25
|
+
from hydpy.models.hland.hland_constants import ILAKE
|
|
26
|
+
|
|
27
|
+
if TYPE_CHECKING:
|
|
28
|
+
from scipy import integrate
|
|
29
|
+
from scipy import stats
|
|
30
|
+
else:
|
|
31
|
+
integrate = exceptiontools.OptionalImport("scipy", ["scipy.integrate"], locals())
|
|
32
|
+
stats = exceptiontools.OptionalImport("stats", ["scipy.stats"], locals())
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class Area(parametertools.Parameter):
|
|
36
|
+
"""Subbasin area [km²]."""
|
|
37
|
+
|
|
38
|
+
NDIM, TYPE, TIME, SPAN = 0, float, None, (1e-10, None)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class NmbZones(parametertools.Parameter):
|
|
42
|
+
"""Number of zones (hydrological response units) in a subbasin [-].
|
|
43
|
+
|
|
44
|
+
|NmbZones| determines the length of most 1-dimensional parameters and sequences.
|
|
45
|
+
Usually, you should first prepare |NmbZones| and define the values of all
|
|
46
|
+
1-dimensional parameters and sequences afterwards:
|
|
47
|
+
|
|
48
|
+
>>> from hydpy.models.hland import *
|
|
49
|
+
>>> parameterstep()
|
|
50
|
+
>>> nmbzones(5)
|
|
51
|
+
>>> icmax.shape
|
|
52
|
+
(5,)
|
|
53
|
+
>>> states.ic.shape
|
|
54
|
+
(5,)
|
|
55
|
+
|
|
56
|
+
Changing the value of |NmbZones| later reshapes the affected parameters and
|
|
57
|
+
sequences and makes it necessary the reset their values:
|
|
58
|
+
|
|
59
|
+
>>> icmax(2.0)
|
|
60
|
+
>>> icmax
|
|
61
|
+
icmax(2.0)
|
|
62
|
+
>>> nmbzones(3)
|
|
63
|
+
>>> icmax
|
|
64
|
+
icmax(?)
|
|
65
|
+
|
|
66
|
+
Re-defining the same value does not delete the already available data:
|
|
67
|
+
|
|
68
|
+
>>> icmax(2.0)
|
|
69
|
+
>>> nmbzones(3)
|
|
70
|
+
>>> icmax
|
|
71
|
+
icmax(2.0)
|
|
72
|
+
|
|
73
|
+
The length of both axes of the 2-dimensional sequence |SRed| agree with |NmbZones|:
|
|
74
|
+
|
|
75
|
+
>>> sred.shape
|
|
76
|
+
(3, 3)
|
|
77
|
+
|
|
78
|
+
Some 2-dimensional sequences reflect differences in snow accumulation within each
|
|
79
|
+
zone. |NmbZones| prepares their shapes also, but therefore requires parameter
|
|
80
|
+
|SClass| to provide the number of snow classes within each zone:
|
|
81
|
+
|
|
82
|
+
>>> states.sp
|
|
83
|
+
Traceback (most recent call last):
|
|
84
|
+
...
|
|
85
|
+
hydpy.core.exceptiontools.AttributeNotReady: Shape information for variable `sp` \
|
|
86
|
+
can only be retrieved after it has been defined.
|
|
87
|
+
|
|
88
|
+
>>> sclass.value = 2
|
|
89
|
+
>>> nmbzones(4)
|
|
90
|
+
>>> states.sp.shape
|
|
91
|
+
(2, 4)
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
NDIM, TYPE, TIME, SPAN = 0, int, None, (1, None)
|
|
95
|
+
|
|
96
|
+
def __call__(self, *args, **kwargs) -> None:
|
|
97
|
+
old_value = exceptiontools.getattr_(self, "value", None)
|
|
98
|
+
super().__call__(*args, **kwargs)
|
|
99
|
+
new_value = self.value
|
|
100
|
+
if new_value != old_value:
|
|
101
|
+
sclass = exceptiontools.getattr_(self.subpars.sclass, "value", None)
|
|
102
|
+
for subpars in self.subpars.pars:
|
|
103
|
+
for par in subpars:
|
|
104
|
+
if (par.NDIM == 1) and (par.name not in ("uh", "sfdist")):
|
|
105
|
+
par.shape = new_value
|
|
106
|
+
if par.NDIM == 2:
|
|
107
|
+
par.shape = new_value, new_value
|
|
108
|
+
for subseqs in self.subpars.pars.model.sequences:
|
|
109
|
+
for seq in subseqs:
|
|
110
|
+
if (seq.NDIM == 1) and (seq.name not in ("quh", "sc")):
|
|
111
|
+
seq.shape = new_value
|
|
112
|
+
elif seq.NDIM == 2:
|
|
113
|
+
if sclass is not None:
|
|
114
|
+
seq.shape = sclass, new_value
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class SClass(parametertools.Parameter):
|
|
118
|
+
"""Number of snow classes in each zone [-].
|
|
119
|
+
|
|
120
|
+
|SClass| determines the length of the first axis of those 2-dimensional sequences
|
|
121
|
+
reflecting differences in snow accumulation within each zone. Therefore, it
|
|
122
|
+
requires parameter |NmbZones| to provide the number of zones within the subbasin:
|
|
123
|
+
|
|
124
|
+
>>> from hydpy.models.hland import *
|
|
125
|
+
>>> parameterstep()
|
|
126
|
+
>>> sclass(1)
|
|
127
|
+
>>> states.sp
|
|
128
|
+
Traceback (most recent call last):
|
|
129
|
+
...
|
|
130
|
+
hydpy.core.exceptiontools.AttributeNotReady: Shape information for variable `sp` \
|
|
131
|
+
can only be retrieved after it has been defined.
|
|
132
|
+
|
|
133
|
+
>>> nmbzones.value = 2
|
|
134
|
+
>>> sclass(3)
|
|
135
|
+
>>> states.sp.shape
|
|
136
|
+
(3, 2)
|
|
137
|
+
|
|
138
|
+
Changing the value of |SClass| later reshapes the affected sequences and makes it
|
|
139
|
+
necessary to reset their values:
|
|
140
|
+
|
|
141
|
+
>>> states.sp = 2.0
|
|
142
|
+
>>> states.sp
|
|
143
|
+
sp([[2.0, 2.0],
|
|
144
|
+
[2.0, 2.0],
|
|
145
|
+
[2.0, 2.0]])
|
|
146
|
+
>>> sclass(2)
|
|
147
|
+
>>> states.sp
|
|
148
|
+
sp([[nan, nan],
|
|
149
|
+
[nan, nan]])
|
|
150
|
+
|
|
151
|
+
Re-defining the same value does not delete the already available data:
|
|
152
|
+
|
|
153
|
+
>>> states.sp = 2.0
|
|
154
|
+
>>> sclass(2)
|
|
155
|
+
>>> states.sp
|
|
156
|
+
sp([[2.0, 2.0],
|
|
157
|
+
[2.0, 2.0]])
|
|
158
|
+
|
|
159
|
+
Additionally, |SClass| determines the shape of the control parameter |SFDist|:
|
|
160
|
+
|
|
161
|
+
>>> sfdist.shape
|
|
162
|
+
(2,)
|
|
163
|
+
"""
|
|
164
|
+
|
|
165
|
+
NDIM, TYPE, TIME, SPAN = 0, int, None, (1, None)
|
|
166
|
+
INIT = 1
|
|
167
|
+
|
|
168
|
+
def __call__(self, *args, **kwargs) -> None:
|
|
169
|
+
old_value = exceptiontools.getattr_(self, "value", None)
|
|
170
|
+
super().__call__(*args, **kwargs)
|
|
171
|
+
new_value = self.value
|
|
172
|
+
if new_value != old_value:
|
|
173
|
+
self.subpars.sfdist.shape = new_value
|
|
174
|
+
nmbzones = exceptiontools.getattr_(self.subpars.nmbzones, "value", None)
|
|
175
|
+
for subseqs in self.subpars.pars.model.sequences:
|
|
176
|
+
for seq in subseqs:
|
|
177
|
+
if seq.NDIM == 2:
|
|
178
|
+
if nmbzones is not None:
|
|
179
|
+
seq.shape = new_value, nmbzones
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
class ZoneType(parametertools.NameParameter):
|
|
183
|
+
"""Type of each zone [-].
|
|
184
|
+
|
|
185
|
+
Parameter |ZoneType| relies on the integer constants defined in module
|
|
186
|
+
|hland_constants| for representing zone types:
|
|
187
|
+
|
|
188
|
+
>>> from hydpy.models.hland import *
|
|
189
|
+
>>> parameterstep("1d")
|
|
190
|
+
>>> nmbzones(6)
|
|
191
|
+
>>> zonetype(FIELD, FOREST, GLACIER, ILAKE, ILAKE, FIELD)
|
|
192
|
+
>>> from hydpy import print_vector
|
|
193
|
+
>>> print_vector(zonetype.values)
|
|
194
|
+
1, 2, 3, 4, 4, 1
|
|
195
|
+
>>> zonetype
|
|
196
|
+
zonetype(FIELD, FOREST, GLACIER, ILAKE, ILAKE, FIELD)
|
|
197
|
+
"""
|
|
198
|
+
|
|
199
|
+
constants = hland_constants.CONSTANTS
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
class ZoneArea(hland_parameters.ParameterComplete):
|
|
203
|
+
"""Zone area [km²]."""
|
|
204
|
+
|
|
205
|
+
NDIM, TYPE, TIME, SPAN = 1, float, None, (0.0, None)
|
|
206
|
+
|
|
207
|
+
def trim(self, lower=None, upper=None) -> bool:
|
|
208
|
+
r"""Trim |ZoneArea| so that :math:`\Sigma ZoneArea = Area` holds and each zone
|
|
209
|
+
area is non-negative.
|
|
210
|
+
|
|
211
|
+
Our example basin is 6 km² large and consists of three zones:
|
|
212
|
+
|
|
213
|
+
>>> from hydpy.models.hland import *
|
|
214
|
+
>>> parameterstep()
|
|
215
|
+
>>> area(6.0)
|
|
216
|
+
>>> nmbzones(3)
|
|
217
|
+
>>> zonetype(FIELD)
|
|
218
|
+
|
|
219
|
+
First, an example with correct data:
|
|
220
|
+
|
|
221
|
+
>>> zonearea(1.0, 2.0, 3.0)
|
|
222
|
+
>>> zonearea
|
|
223
|
+
zonearea(1.0, 2.0, 3.0)
|
|
224
|
+
|
|
225
|
+
Second, an example with a single zone with a negative area:
|
|
226
|
+
|
|
227
|
+
>>> zonearea(-1.0, 2.0, 4.0)
|
|
228
|
+
>>> zonearea
|
|
229
|
+
zonearea(0.0, 2.0, 4.0)
|
|
230
|
+
|
|
231
|
+
Third, an example with too low zone areas:
|
|
232
|
+
|
|
233
|
+
>>> zonearea(0.5, 1.0, 1.5)
|
|
234
|
+
>>> zonearea
|
|
235
|
+
zonearea(1.0, 2.0, 3.0)
|
|
236
|
+
|
|
237
|
+
Fourth, an example with too high zone areas:
|
|
238
|
+
|
|
239
|
+
>>> zonearea(2.0, 4.0, 6.0)
|
|
240
|
+
>>> zonearea
|
|
241
|
+
zonearea(1.0, 2.0, 3.0)
|
|
242
|
+
|
|
243
|
+
Fifth, a combined example:
|
|
244
|
+
|
|
245
|
+
>>> zonearea(-1.0, 1.0, 2.0)
|
|
246
|
+
>>> zonearea
|
|
247
|
+
zonearea(0.0, 2.0, 4.0)
|
|
248
|
+
"""
|
|
249
|
+
area = self.subpars.area.value
|
|
250
|
+
areas = numpy.clip(self.values, 0.0, numpy.inf)
|
|
251
|
+
areas *= area / numpy.sum(areas)
|
|
252
|
+
if lower is None:
|
|
253
|
+
lower = areas
|
|
254
|
+
if upper is None:
|
|
255
|
+
upper = areas
|
|
256
|
+
return super().trim(lower, upper)
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
class Psi(parametertools.Parameter):
|
|
260
|
+
"""Fraction of the actual sealing of zones classified as |SEALED| [-]."""
|
|
261
|
+
|
|
262
|
+
NDIM, TYPE, TIME, SPAN = 0, float, None, (0.01, 1.0)
|
|
263
|
+
INIT = 1.0
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
class ZoneZ(hland_parameters.ParameterComplete):
|
|
267
|
+
"""Zone elevation [100m]."""
|
|
268
|
+
|
|
269
|
+
NDIM, TYPE, TIME, SPAN = 1, float, None, (None, None)
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
class PCorr(hland_parameters.ParameterComplete):
|
|
273
|
+
"""General precipitation correction factor [-]."""
|
|
274
|
+
|
|
275
|
+
NDIM, TYPE, TIME, SPAN = 1, float, None, (0.0, None)
|
|
276
|
+
INIT = 1.0
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
class PCAlt(hland_parameters.ParameterComplete):
|
|
280
|
+
"""Elevation correction factor for precipitation [1/100m]."""
|
|
281
|
+
|
|
282
|
+
NDIM, TYPE, TIME, SPAN = 1, float, None, (None, None)
|
|
283
|
+
INIT = 0.1
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
class RfCF(hland_parameters.ParameterComplete):
|
|
287
|
+
"""Rainfall correction factor [-]."""
|
|
288
|
+
|
|
289
|
+
NDIM, TYPE, TIME, SPAN = 1, float, None, (0.0, None)
|
|
290
|
+
INIT = 1.0
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
class SfCF(hland_parameters.ParameterComplete):
|
|
294
|
+
"""Snowfall correction factor [-]."""
|
|
295
|
+
|
|
296
|
+
NDIM, TYPE, TIME, SPAN = 1, float, None, (0.0, None)
|
|
297
|
+
INIT = 1.0
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
class TCorr(hland_parameters.ParameterNoGlacier):
|
|
301
|
+
"""General temperature correction addend [-]."""
|
|
302
|
+
|
|
303
|
+
NDIM, TYPE, TIME, SPAN = 1, float, None, (None, None)
|
|
304
|
+
INIT = 0.0
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
class TCAlt(hland_parameters.ParameterComplete):
|
|
308
|
+
"""Elevation correction factor for temperature [-1°C/100m]."""
|
|
309
|
+
|
|
310
|
+
NDIM, TYPE, TIME, SPAN = 1, float, None, (None, None)
|
|
311
|
+
INIT = 0.6
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
class IcMax(hland_parameters.ParameterInterception):
|
|
315
|
+
"""Maximum interception storage [mm]."""
|
|
316
|
+
|
|
317
|
+
NDIM, TYPE, TIME, SPAN = 1, float, None, (0.0, None)
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
class SFDist(parametertools.Parameter):
|
|
321
|
+
"""Distribution of snowfall [-].
|
|
322
|
+
|
|
323
|
+
Parameter |SFDist| handles multiple adjustment factors for snowfall, one for each
|
|
324
|
+
snow class, to introduce spatial heterogeneity to the snow depth within each zone.
|
|
325
|
+
If we, for example, define three snow classes per zone but assign the neutral value
|
|
326
|
+
1.0 to |SFDist|, all snow classes will receive the same amount of liquid and frozen
|
|
327
|
+
snowfall (everything else will also be identical, so defining three snow classes
|
|
328
|
+
instead of one is just a waste of computation time):
|
|
329
|
+
|
|
330
|
+
>>> from hydpy.models.hland import *
|
|
331
|
+
>>> parameterstep()
|
|
332
|
+
>>> sclass(3)
|
|
333
|
+
>>> sfdist(1.0)
|
|
334
|
+
>>> sfdist
|
|
335
|
+
sfdist(1.0)
|
|
336
|
+
|
|
337
|
+
|SFDist| norms the given values. If we assign 0.1, 0.2, and 0.3, the snow classes
|
|
338
|
+
receive 50 %, 100 %, and 150 % of the average snowfall of their respective zone:
|
|
339
|
+
|
|
340
|
+
>>> sfdist(0.1, 0.2, 0.3)
|
|
341
|
+
>>> sfdist
|
|
342
|
+
sfdist(0.5, 1.0, 1.5)
|
|
343
|
+
|
|
344
|
+
|SFDist| provides two convenient alternatives for defining multiple factors with
|
|
345
|
+
single keyword arguments. To illustrate how they work, we first define a test
|
|
346
|
+
function that accepts a keyword argument, passes it to a |SFDist| instance for the
|
|
347
|
+
cases of one to five snow classes, and prints the respective snow class-specific
|
|
348
|
+
factors:
|
|
349
|
+
|
|
350
|
+
>>> from hydpy import print_vector
|
|
351
|
+
>>> def test(**kwargs):
|
|
352
|
+
... for nmb in range(1, 6):
|
|
353
|
+
... sclass(nmb)
|
|
354
|
+
... sfdist(**kwargs)
|
|
355
|
+
... print_vector(sfdist.values)
|
|
356
|
+
|
|
357
|
+
The first available keyword is `linear`. Using it, |SFDist| calculates its factors
|
|
358
|
+
in agreement with the original *HBV96* implementation. For the lowest possible
|
|
359
|
+
value, 0.0, all adjustment factors are one:
|
|
360
|
+
|
|
361
|
+
>>> test(linear=0.0)
|
|
362
|
+
1.0
|
|
363
|
+
1.0, 1.0
|
|
364
|
+
1.0, 1.0, 1.0
|
|
365
|
+
1.0, 1.0, 1.0, 1.0
|
|
366
|
+
1.0, 1.0, 1.0, 1.0, 1.0
|
|
367
|
+
|
|
368
|
+
For the highest possible value, 1.0, the first snow class receives no snowfall,
|
|
369
|
+
while the last snow receives twice the zone's average snowfall. |SFDist|
|
|
370
|
+
interpolates the factors of the other snow classes linearly:
|
|
371
|
+
|
|
372
|
+
>>> test(linear=1.0)
|
|
373
|
+
1.0
|
|
374
|
+
0.0, 2.0
|
|
375
|
+
0.0, 1.0, 2.0
|
|
376
|
+
0.0, 0.666667, 1.333333, 2.0
|
|
377
|
+
0.0, 0.5, 1.0, 1.5, 2.0
|
|
378
|
+
|
|
379
|
+
For a value of 0.5, the first and the last snow class receive 50 % and 150 % of the
|
|
380
|
+
zone's average snowfall:
|
|
381
|
+
|
|
382
|
+
>>> test(linear=0.5)
|
|
383
|
+
1.0
|
|
384
|
+
0.5, 1.5
|
|
385
|
+
0.5, 1.0, 1.5
|
|
386
|
+
0.5, 0.833333, 1.166667, 1.5
|
|
387
|
+
0.5, 0.75, 1.0, 1.25, 1.5
|
|
388
|
+
|
|
389
|
+
The first available keyword is `lognormal`. Here, |SFDist| calculates factors
|
|
390
|
+
resulting in a lognormal distribution of snowfall, similarly as implemented in
|
|
391
|
+
the COSERO model :cite:p:`ref-Frey2015CoseroSnow`. Again, the lowest possible
|
|
392
|
+
value,
|
|
393
|
+
0.0, results in uniform snow distributions:
|
|
394
|
+
|
|
395
|
+
>>> test(lognormal=0.0)
|
|
396
|
+
1.0
|
|
397
|
+
1.0, 1.0
|
|
398
|
+
1.0, 1.0, 1.0
|
|
399
|
+
1.0, 1.0, 1.0, 1.0
|
|
400
|
+
1.0, 1.0, 1.0, 1.0, 1.0
|
|
401
|
+
|
|
402
|
+
In the following examples, we increase the scale factor from 0.01 to 0.1 to 1.0.
|
|
403
|
+
The higher the scale factor, the more snow concentrates in the last snow class:
|
|
404
|
+
|
|
405
|
+
>>> test(lognormal=0.01)
|
|
406
|
+
1.0
|
|
407
|
+
0.992021, 1.007979
|
|
408
|
+
0.989116, 0.999953, 1.010931
|
|
409
|
+
0.987332, 0.996711, 1.003204, 1.012754
|
|
410
|
+
0.986061, 0.994647, 0.999951, 1.005284, 1.014057
|
|
411
|
+
|
|
412
|
+
>>> test(lognormal=0.1)
|
|
413
|
+
1.0
|
|
414
|
+
0.920344, 1.079656
|
|
415
|
+
0.893412, 0.995313, 1.111276
|
|
416
|
+
0.877282, 0.963406, 1.028038, 1.131273
|
|
417
|
+
0.865966, 0.943604, 0.995118, 1.049519, 1.145792
|
|
418
|
+
|
|
419
|
+
>>> test(lognormal=1.0)
|
|
420
|
+
1.0
|
|
421
|
+
0.317311, 1.682689
|
|
422
|
+
0.228763, 0.624994, 2.146243
|
|
423
|
+
0.188069, 0.446552, 0.854969, 2.51041
|
|
424
|
+
0.163826, 0.361372, 0.612984, 1.047213, 2.814604
|
|
425
|
+
|
|
426
|
+
Theoretically, higher scale factors are allowed. However, 1.0 results in highly
|
|
427
|
+
heterogeneous snow distributions already.
|
|
428
|
+
|
|
429
|
+
Wrong usage results in the usual error messages:
|
|
430
|
+
|
|
431
|
+
>>> sfdist(normal=1.0)
|
|
432
|
+
Traceback (most recent call last):
|
|
433
|
+
...
|
|
434
|
+
NotImplementedError: The value(s) of parameter `sfdist` of element `?` could not \
|
|
435
|
+
be set based on the given keyword arguments.
|
|
436
|
+
|
|
437
|
+
>>> sfdist(linear=1.0, lognormal=1.0)
|
|
438
|
+
Traceback (most recent call last):
|
|
439
|
+
...
|
|
440
|
+
NotImplementedError: The value(s) of parameter `sfdist` of element `?` could not \
|
|
441
|
+
be set based on the given keyword arguments.
|
|
442
|
+
|
|
443
|
+
>>> sfdist(1.0, lognormal=1.0)
|
|
444
|
+
Traceback (most recent call last):
|
|
445
|
+
...
|
|
446
|
+
ValueError: For parameter `sfdist` of element `?` both positional and keyword \
|
|
447
|
+
arguments are given, which is ambiguous.
|
|
448
|
+
"""
|
|
449
|
+
|
|
450
|
+
NDIM, TYPE, TIME, SPAN = 1, float, None, (0.0, None)
|
|
451
|
+
INIT = 1.0
|
|
452
|
+
|
|
453
|
+
def __call__(self, *args, **kwargs) -> None:
|
|
454
|
+
sclass = self.shape[0]
|
|
455
|
+
idx = self._find_kwargscombination(args, kwargs, ({"linear"}, {"lognormal"}))
|
|
456
|
+
if idx is None:
|
|
457
|
+
super().__call__(*args, **kwargs)
|
|
458
|
+
elif idx == 0:
|
|
459
|
+
super().__call__(self._linear(kwargs["linear"], sclass))
|
|
460
|
+
else:
|
|
461
|
+
super().__call__(self._lognormal(sclass, kwargs["lognormal"]))
|
|
462
|
+
self.value /= sum(self.value) / sclass
|
|
463
|
+
|
|
464
|
+
@staticmethod
|
|
465
|
+
@functools.lru_cache
|
|
466
|
+
def _linear(factor, sclass):
|
|
467
|
+
if sclass == 1:
|
|
468
|
+
values = (1.0,)
|
|
469
|
+
else:
|
|
470
|
+
values = (
|
|
471
|
+
factor * 2.0 * numpy.arange(sclass) / (sclass - 1) + (1.0 - factor)
|
|
472
|
+
) / sclass
|
|
473
|
+
return values
|
|
474
|
+
|
|
475
|
+
@staticmethod
|
|
476
|
+
@functools.lru_cache
|
|
477
|
+
def _lognormal(sclass, scale: float) -> VectorFloat:
|
|
478
|
+
values = numpy.ones(sclass, dtype=config.NP_FLOAT)
|
|
479
|
+
if scale > 0.0:
|
|
480
|
+
for idx in range(sclass):
|
|
481
|
+
values[idx] = integrate.quad(
|
|
482
|
+
lambda x: stats.lognorm.ppf(x, scale),
|
|
483
|
+
idx / sclass,
|
|
484
|
+
(idx + 1) / sclass,
|
|
485
|
+
)[0]
|
|
486
|
+
return values
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
class SMax(hland_parameters.ParameterLand):
|
|
490
|
+
"""Maximum snow water equivalent [mm]."""
|
|
491
|
+
|
|
492
|
+
NDIM, TYPE, TIME, SPAN = 1, float, None, (0.0, None)
|
|
493
|
+
INIT = numpy.inf
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
class SRed(parametertools.Parameter):
|
|
497
|
+
"""Snow redistribution paths [-].
|
|
498
|
+
|
|
499
|
+
|SRed| is a 2-dimensional parameter that handles weighting factors for all possible
|
|
500
|
+
zone connections. The source zones vary on the rows and the target zones on the
|
|
501
|
+
columns. In the following example, zone one sends all snow available for
|
|
502
|
+
redistribution to zone three. Zone two sends 50 % to zone four and 50 % to zone
|
|
503
|
+
five. Zone six sends 40 % to zone two, 40 % to zone three, and 20 % to zone four:
|
|
504
|
+
|
|
505
|
+
>>> from hydpy.models.hland import *
|
|
506
|
+
>>> parameterstep()
|
|
507
|
+
>>> nmbzones(6)
|
|
508
|
+
>>> zonetype(FIELD)
|
|
509
|
+
>>> sred([[0.0, 0.0, 1.0, 0.0, 0.0, 0.0],
|
|
510
|
+
... [0.0, 0.0, 0.0, 0.5, 0.5, 0.0],
|
|
511
|
+
... [0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
512
|
+
... [0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
513
|
+
... [0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
514
|
+
... [0.0, 0.4, 0.4, 0.2, 0.0, 0.0]])
|
|
515
|
+
>>> sred
|
|
516
|
+
sred([[0.0, 0.0, 1.0, 0.0, 0.0, 0.0],
|
|
517
|
+
[0.0, 0.0, 0.0, 0.5, 0.5, 0.0],
|
|
518
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
519
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
520
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
521
|
+
[0.0, 0.4, 0.4, 0.2, 0.0, 0.0]])
|
|
522
|
+
|
|
523
|
+
A zone can either redistribute no snow at all (we then call it a "dead end") or
|
|
524
|
+
needs to send 100 % of the snow available for redistribution. Hence, the sums of
|
|
525
|
+
the individual rows must be either 0.0 or 1.0. Method |SRed.verify| checks for
|
|
526
|
+
possible violations of this requirement (by calling method |SRed.verify_sums|):
|
|
527
|
+
|
|
528
|
+
>>> sred([[0.0, 0.0, 1.0, 0.0, 0.0, 0.0],
|
|
529
|
+
... [0.0, 0.0, 0.0, 0.0, 0.5, 0.5],
|
|
530
|
+
... [0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
531
|
+
... [0.0, 0.0, 0.0, 0.0, 0.4, 0.5],
|
|
532
|
+
... [0.0, 0.1, 0.0, 0.0, 0.0, 0.0],
|
|
533
|
+
... [0.0, 0.4, 0.4, 0.2, 0.0, 0.0]])
|
|
534
|
+
>>> sred.verify()
|
|
535
|
+
Traceback (most recent call last):
|
|
536
|
+
...
|
|
537
|
+
RuntimeError: The sum(s) of the following row(s) of parameter `sred` of element \
|
|
538
|
+
`?` are neither 0.0 nor 1.0: 3 and 4.
|
|
539
|
+
|
|
540
|
+
Zones of type |ILAKE| possess no snow module. Hence, they never release any snow
|
|
541
|
+
for redistribution and method |SRed.verify| checks for possible unused weighting
|
|
542
|
+
factors in the relevant rows (by calling method |SRed.verify_lakes|):
|
|
543
|
+
|
|
544
|
+
>>> zonetype(FIELD, FIELD, FIELD, ILAKE, FIELD, ILAKE)
|
|
545
|
+
>>> sred([[0.0, 1.0, 0.0, 0.0, 0.0, 0.0],
|
|
546
|
+
... [0.0, 0.0, 1.0, 0.0, 0.0, 0.0],
|
|
547
|
+
... [0.0, 0.0, 0.0, 0.0, 1.0, 0.0],
|
|
548
|
+
... [0.0, 0.0, 0.0, 0.0, 1.0, 0.0],
|
|
549
|
+
... [0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
|
|
550
|
+
... [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]])
|
|
551
|
+
>>> sred.verify()
|
|
552
|
+
Traceback (most recent call last):
|
|
553
|
+
...
|
|
554
|
+
RuntimeError: Internal lake zones cannot be involved in snow redistribution, so \
|
|
555
|
+
the sums of all rows of parameter `sred` of element `?` corresponding to internal lake \
|
|
556
|
+
zones must be zero, which is not the case for the row(s): 3.
|
|
557
|
+
|
|
558
|
+
For the same reason, internal lakes cannot receive and accumulate any redistributed
|
|
559
|
+
snow. Therefore, method |SRed.verify| additionally checks for possible problematic
|
|
560
|
+
weighting factors in the relevant columns (by calling method |SRed.verify_lakes|):
|
|
561
|
+
|
|
562
|
+
>>> sred([[0.0, 0.5, 0.0, 0.0, 0.0, 0.5],
|
|
563
|
+
... [0.0, 0.0, 1.0, 0.0, 0.0, 0.0],
|
|
564
|
+
... [0.0, 0.0, 0.0, 1.0, 0.0, 0.0],
|
|
565
|
+
... [0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
566
|
+
... [0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
|
|
567
|
+
... [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]])
|
|
568
|
+
>>> sred.verify()
|
|
569
|
+
Traceback (most recent call last):
|
|
570
|
+
...
|
|
571
|
+
RuntimeError: Internal lake zones cannot be involved in snow redistribution, so \
|
|
572
|
+
the sums of all columns of parameter `sred` of element `?` corresponding to internal \
|
|
573
|
+
lake zones must be zero, which is not the case for the column(s): 3 and 5.
|
|
574
|
+
|
|
575
|
+
The snow redistribution routine of |hland| does not allow for any cycles. Method
|
|
576
|
+
|SRed.verify| checks for possible cycles by calling method |SRed.verify_order|:
|
|
577
|
+
|
|
578
|
+
>>> zonetype(FIELD)
|
|
579
|
+
>>> sred([[0.0, 0.0, 1.0, 0.0, 0.0, 0.0],
|
|
580
|
+
... [0.0, 0.0, 0.0, 0.0, 0.5, 0.5],
|
|
581
|
+
... [0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
582
|
+
... [0.0, 0.0, 0.0, 0.0, 0.5, 0.5],
|
|
583
|
+
... [0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
584
|
+
... [0.0, 0.4, 0.4, 0.2, 0.0, 0.0]])
|
|
585
|
+
>>> sred.verify()
|
|
586
|
+
Traceback (most recent call last):
|
|
587
|
+
...
|
|
588
|
+
RuntimeError: The weighting factors of parameter `sred` of element `?` define at \
|
|
589
|
+
least one cycle: (1, 5) and (5, 1).
|
|
590
|
+
|
|
591
|
+
Note that method |SRed.verify_order| relies on the |SRedOrder.update| method of
|
|
592
|
+
parameter |SRedOrder| but resets its values afterwards:
|
|
593
|
+
|
|
594
|
+
>>> derived.sredorder.shape = (1, 2)
|
|
595
|
+
>>> derived.sredorder.values = [[0, 1]]
|
|
596
|
+
>>> old_values = derived.sredorder.values.copy()
|
|
597
|
+
>>> sred.values[1, -2:] = 1.0, 0.0
|
|
598
|
+
>>> sred.verify_order()
|
|
599
|
+
Traceback (most recent call last):
|
|
600
|
+
...
|
|
601
|
+
RuntimeError: The weighting factors of parameter `sred` of element `?` define at \
|
|
602
|
+
least one cycle: (3, 5) and (5, 3).
|
|
603
|
+
>>> derived.sredorder
|
|
604
|
+
sredorder(0, 1)
|
|
605
|
+
|
|
606
|
+
Parameter |SRed| provides two options to define the weighting factors with little
|
|
607
|
+
effort. The first option works by specifying the number of target zones. If we
|
|
608
|
+
set the number of target zones to one, |SRed| determines the next lower target for
|
|
609
|
+
each zone that is not a dead-end:
|
|
610
|
+
|
|
611
|
+
>>> zonetype(GLACIER, FIELD, FOREST, SEALED, ILAKE, FOREST)
|
|
612
|
+
>>> zonez(6.0, 5.0, 4.0, 3.0, 2.0, 1.0)
|
|
613
|
+
>>> zonearea.values = 1.0
|
|
614
|
+
>>> sred(n_zones=1)
|
|
615
|
+
|
|
616
|
+
For brevity, parameter |SRed| returns string representations based on these options
|
|
617
|
+
when possible:
|
|
618
|
+
|
|
619
|
+
>>> sred
|
|
620
|
+
sred(n_zones=1)
|
|
621
|
+
|
|
622
|
+
Clear the contents of the |KeywordArguments| object returned by property
|
|
623
|
+
|SRed.keywordarguments| to see the actual parameter values:
|
|
624
|
+
|
|
625
|
+
>>> sred.keywordarguments.clear()
|
|
626
|
+
>>> sred
|
|
627
|
+
sred([[0.0, 1.0, 0.0, 0.0, 0.0, 0.0],
|
|
628
|
+
[0.0, 0.0, 1.0, 0.0, 0.0, 0.0],
|
|
629
|
+
[0.0, 0.0, 0.0, 1.0, 0.0, 0.0],
|
|
630
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
|
|
631
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
632
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0]])
|
|
633
|
+
|
|
634
|
+
For two target zones (and identical zone areas), the weights of the next two lower
|
|
635
|
+
zones are 0.5:
|
|
636
|
+
|
|
637
|
+
>>> sred(n_zones=2)
|
|
638
|
+
>>> sred.keywordarguments.clear()
|
|
639
|
+
>>> sred
|
|
640
|
+
sred([[0.0, 0.5, 0.5, 0.0, 0.0, 0.0],
|
|
641
|
+
[0.0, 0.0, 0.5, 0.5, 0.0, 0.0],
|
|
642
|
+
[0.0, 0.0, 0.0, 0.5, 0.0, 0.5],
|
|
643
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
|
|
644
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
645
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0]])
|
|
646
|
+
|
|
647
|
+
You can specify an arbitrarily high numbes of target zones. Parameter |SRed|
|
|
648
|
+
adjusts the given value to the number of actually available target zones:
|
|
649
|
+
|
|
650
|
+
>>> sred(n_zones=999)
|
|
651
|
+
>>> sred.keywordarguments.clear()
|
|
652
|
+
>>> sred
|
|
653
|
+
sred([[0.0, 0.25, 0.25, 0.25, 0.0, 0.25],
|
|
654
|
+
[0.0, 0.0, 0.333333, 0.333333, 0.0, 0.333333],
|
|
655
|
+
[0.0, 0.0, 0.0, 0.5, 0.0, 0.5],
|
|
656
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
|
|
657
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
658
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0]])
|
|
659
|
+
|
|
660
|
+
After defining the same elevation for the second and the third zone, the first zone
|
|
661
|
+
redistributes the same snow amount to both of them. Additionally, both zones
|
|
662
|
+
redistribute their own snow to the fourth zone:
|
|
663
|
+
|
|
664
|
+
>>> zonez(6.0, 5.0, 5.0, 3.0, 2.0, 1.0)
|
|
665
|
+
|
|
666
|
+
>>> sred(n_zones=1)
|
|
667
|
+
>>> sred.keywordarguments.clear()
|
|
668
|
+
>>> sred
|
|
669
|
+
sred([[0.0, 0.5, 0.5, 0.0, 0.0, 0.0],
|
|
670
|
+
[0.0, 0.0, 0.0, 1.0, 0.0, 0.0],
|
|
671
|
+
[0.0, 0.0, 0.0, 1.0, 0.0, 0.0],
|
|
672
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
|
|
673
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
674
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0]])
|
|
675
|
+
|
|
676
|
+
>>> sred(n_zones=2)
|
|
677
|
+
>>> sred.keywordarguments.clear()
|
|
678
|
+
>>> sred
|
|
679
|
+
sred([[0.0, 0.5, 0.5, 0.0, 0.0, 0.0],
|
|
680
|
+
[0.0, 0.0, 0.0, 0.5, 0.0, 0.5],
|
|
681
|
+
[0.0, 0.0, 0.0, 0.5, 0.0, 0.5],
|
|
682
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
|
|
683
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
684
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0]])
|
|
685
|
+
|
|
686
|
+
>>> sred(n_zones=999)
|
|
687
|
+
>>> sred.keywordarguments.clear()
|
|
688
|
+
>>> sred
|
|
689
|
+
sred([[0.0, 0.25, 0.25, 0.25, 0.0, 0.25],
|
|
690
|
+
[0.0, 0.0, 0.0, 0.5, 0.0, 0.5],
|
|
691
|
+
[0.0, 0.0, 0.0, 0.5, 0.0, 0.5],
|
|
692
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
|
|
693
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
694
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0]])
|
|
695
|
+
|
|
696
|
+
For all zones lying on the same elevation, no redistribution occurs:
|
|
697
|
+
|
|
698
|
+
>>> zonez(1.0)
|
|
699
|
+
|
|
700
|
+
>>> sred(n_zones=1)
|
|
701
|
+
>>> sred.keywordarguments.clear()
|
|
702
|
+
>>> sred
|
|
703
|
+
sred(0.0)
|
|
704
|
+
|
|
705
|
+
>>> sred(n_zones=2)
|
|
706
|
+
>>> sred.keywordarguments.clear()
|
|
707
|
+
>>> sred
|
|
708
|
+
sred(0.0)
|
|
709
|
+
|
|
710
|
+
>>> sred(n_zones=999)
|
|
711
|
+
>>> sred.keywordarguments.clear()
|
|
712
|
+
>>> sred
|
|
713
|
+
sred(0.0)
|
|
714
|
+
|
|
715
|
+
The following examples demonstrate that the weights' calculation works well for
|
|
716
|
+
unsorted elevations:
|
|
717
|
+
|
|
718
|
+
>>> zonetype(FIELD, FOREST, FOREST, ILAKE, GLACIER, SEALED)
|
|
719
|
+
>>> zonez(5.0, 4.0, 1.0, 2.0, 6.0, 3.0)
|
|
720
|
+
|
|
721
|
+
>>> sred(n_zones=1)
|
|
722
|
+
>>> sred.keywordarguments.clear()
|
|
723
|
+
>>> sred
|
|
724
|
+
sred([[0.0, 1.0, 0.0, 0.0, 0.0, 0.0],
|
|
725
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
|
|
726
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
727
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
728
|
+
[1.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
729
|
+
[0.0, 0.0, 1.0, 0.0, 0.0, 0.0]])
|
|
730
|
+
|
|
731
|
+
>>> sred(n_zones=2)
|
|
732
|
+
>>> sred.keywordarguments.clear()
|
|
733
|
+
>>> sred
|
|
734
|
+
sred([[0.0, 0.5, 0.0, 0.0, 0.0, 0.5],
|
|
735
|
+
[0.0, 0.0, 0.5, 0.0, 0.0, 0.5],
|
|
736
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
737
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
738
|
+
[0.5, 0.5, 0.0, 0.0, 0.0, 0.0],
|
|
739
|
+
[0.0, 0.0, 1.0, 0.0, 0.0, 0.0]])
|
|
740
|
+
|
|
741
|
+
>>> sred(n_zones=999)
|
|
742
|
+
>>> sred.keywordarguments.clear()
|
|
743
|
+
>>> sred
|
|
744
|
+
sred([[0.0, 0.333333, 0.333333, 0.0, 0.0, 0.333333],
|
|
745
|
+
[0.0, 0.0, 0.5, 0.0, 0.0, 0.5],
|
|
746
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
747
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
748
|
+
[0.25, 0.25, 0.25, 0.0, 0.0, 0.25],
|
|
749
|
+
[0.0, 0.0, 1.0, 0.0, 0.0, 0.0]])
|
|
750
|
+
|
|
751
|
+
For unequal zone areas, the calculated weights reflect the relations between the
|
|
752
|
+
respective source and target zones. The idea is that larger target zones have
|
|
753
|
+
larger contact surfaces with their source zones than smaller ones. This approach
|
|
754
|
+
prevents building extreme snow towers in small target zones:
|
|
755
|
+
|
|
756
|
+
>>> zonearea.values = 1.0, 2.0, 3.0, 4.0, 5.0, 6.0
|
|
757
|
+
|
|
758
|
+
>>> sred(n_zones=1)
|
|
759
|
+
>>> sred.keywordarguments.clear()
|
|
760
|
+
>>> sred
|
|
761
|
+
sred([[0.0, 1.0, 0.0, 0.0, 0.0, 0.0],
|
|
762
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
|
|
763
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
764
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
765
|
+
[1.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
766
|
+
[0.0, 0.0, 1.0, 0.0, 0.0, 0.0]])
|
|
767
|
+
|
|
768
|
+
>>> sred(n_zones=2)
|
|
769
|
+
>>> sred.keywordarguments.clear()
|
|
770
|
+
>>> sred
|
|
771
|
+
sred([[0.0, 0.25, 0.0, 0.0, 0.0, 0.75],
|
|
772
|
+
[0.0, 0.0, 0.333333, 0.0, 0.0, 0.666667],
|
|
773
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
774
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
775
|
+
[0.333333, 0.666667, 0.0, 0.0, 0.0, 0.0],
|
|
776
|
+
[0.0, 0.0, 1.0, 0.0, 0.0, 0.0]])
|
|
777
|
+
|
|
778
|
+
>>> sred(n_zones=999)
|
|
779
|
+
>>> sred.keywordarguments.clear()
|
|
780
|
+
>>> sred
|
|
781
|
+
sred([[0.0, 0.181818, 0.272727, 0.0, 0.0, 0.545455],
|
|
782
|
+
[0.0, 0.0, 0.333333, 0.0, 0.0, 0.666667],
|
|
783
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
784
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
785
|
+
[0.083333, 0.166667, 0.25, 0.0, 0.0, 0.5],
|
|
786
|
+
[0.0, 0.0, 1.0, 0.0, 0.0, 0.0]])
|
|
787
|
+
|
|
788
|
+
Instead of supplying the number of target zones directly, on can define the maximum
|
|
789
|
+
height of redistribution. For a source zone at an elevation `x`, parameter |SRed|
|
|
790
|
+
searches for zones that lie within the interval :math:`[x - d\\_height, x)`. If it
|
|
791
|
+
does not find one, it selects at least the next lower target zone(s), if existing:
|
|
792
|
+
|
|
793
|
+
>>> zonez(5.0, 5.0, 1.0, 2.0, 6.0, 3.0)
|
|
794
|
+
|
|
795
|
+
>>> sred(d_height=0.0)
|
|
796
|
+
>>> sred
|
|
797
|
+
sred(d_height=0.0)
|
|
798
|
+
>>> sred.keywordarguments.clear()
|
|
799
|
+
>>> sred
|
|
800
|
+
sred([[0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
|
|
801
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
|
|
802
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
803
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
804
|
+
[0.333333, 0.666667, 0.0, 0.0, 0.0, 0.0],
|
|
805
|
+
[0.0, 0.0, 1.0, 0.0, 0.0, 0.0]])
|
|
806
|
+
|
|
807
|
+
>>> sred(d_height=2.0)
|
|
808
|
+
>>> sred.keywordarguments.clear()
|
|
809
|
+
>>> sred
|
|
810
|
+
sred([[0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
|
|
811
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 1.0],
|
|
812
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
813
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
814
|
+
[0.333333, 0.666667, 0.0, 0.0, 0.0, 0.0],
|
|
815
|
+
[0.0, 0.0, 1.0, 0.0, 0.0, 0.0]])
|
|
816
|
+
|
|
817
|
+
>>> sred(d_height=10.0)
|
|
818
|
+
>>> sred.keywordarguments.clear()
|
|
819
|
+
>>> sred
|
|
820
|
+
sred([[0.0, 0.0, 0.333333, 0.0, 0.0, 0.666667],
|
|
821
|
+
[0.0, 0.0, 0.333333, 0.0, 0.0, 0.666667],
|
|
822
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
823
|
+
[0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
|
|
824
|
+
[0.083333, 0.166667, 0.25, 0.0, 0.0, 0.5],
|
|
825
|
+
[0.0, 0.0, 1.0, 0.0, 0.0, 0.0]])
|
|
826
|
+
|
|
827
|
+
Passing multiple keyword arguments or a positional and a keyword argument at once
|
|
828
|
+
results in the following error messages:
|
|
829
|
+
|
|
830
|
+
>>> sred(n_zones=1, d_height=0.0)
|
|
831
|
+
Traceback (most recent call last):
|
|
832
|
+
...
|
|
833
|
+
ValueError: Parameter `sred` of element `?` accepts at most a single keyword \
|
|
834
|
+
argument but 2 are given.
|
|
835
|
+
|
|
836
|
+
>>> sred(0.0, d_height=0.0)
|
|
837
|
+
Traceback (most recent call last):
|
|
838
|
+
...
|
|
839
|
+
ValueError: For parameter `sred` of element `?` both positional and keyword \
|
|
840
|
+
arguments are given, which is ambiguous.
|
|
841
|
+
"""
|
|
842
|
+
|
|
843
|
+
NDIM, TYPE, TIME, SPAN = 2, float, None, (0.0, None)
|
|
844
|
+
INIT = 0.0
|
|
845
|
+
|
|
846
|
+
_keywordarguments = parametertools.KeywordArguments(False)
|
|
847
|
+
|
|
848
|
+
def __init__(self, subvars) -> None:
|
|
849
|
+
super().__init__(subvars)
|
|
850
|
+
self._keywordarguments = parametertools.KeywordArguments(False)
|
|
851
|
+
|
|
852
|
+
def __call__(self, *args, **kwargs) -> None:
|
|
853
|
+
self._keywordarguments.clear()
|
|
854
|
+
if ("n_zones" in kwargs) or ("d_height" in kwargs):
|
|
855
|
+
if args:
|
|
856
|
+
super().__call__(*args, **kwargs)
|
|
857
|
+
if len(kwargs) > 1:
|
|
858
|
+
raise ValueError(
|
|
859
|
+
f"Parameter {objecttools.elementphrase(self)} accepts at most a "
|
|
860
|
+
f"single keyword argument but {len(kwargs)} are given."
|
|
861
|
+
)
|
|
862
|
+
self._keywordarguments.add(*tuple(kwargs.items())[0])
|
|
863
|
+
try:
|
|
864
|
+
if "n_zones" in kwargs:
|
|
865
|
+
args = (self._prepare_nzones(kwargs.pop("n_zones")),)
|
|
866
|
+
elif "d_height" in kwargs:
|
|
867
|
+
args = (self._prepare_dheight(kwargs.pop("d_height")),)
|
|
868
|
+
super().__call__(*args, **kwargs)
|
|
869
|
+
except BaseException as exc:
|
|
870
|
+
self._keywordarguments.clear()
|
|
871
|
+
raise exc
|
|
872
|
+
|
|
873
|
+
def _prepare_nzones(self, nzones: int) -> MatrixFloat:
|
|
874
|
+
return self._prepare(self.subpars.nmbzones.value * (nzones,))
|
|
875
|
+
|
|
876
|
+
def _prepare_dheight(self, dheight: float) -> MatrixFloat:
|
|
877
|
+
zonez = self.subpars.zonez.values
|
|
878
|
+
nzones = (numpy.sum((z > zonez) * (zonez >= (z - dheight))) for z in zonez)
|
|
879
|
+
return self._prepare(tuple(max(n, 1) for n in nzones))
|
|
880
|
+
|
|
881
|
+
def _prepare(self, nzones: tuple[int, ...]) -> MatrixFloat:
|
|
882
|
+
nmbzones = self.subpars.nmbzones.value
|
|
883
|
+
zonearea = self.subpars.zonearea.value
|
|
884
|
+
types_ = self.subpars.zonetype.value
|
|
885
|
+
zonez = self.subpars.zonez.value
|
|
886
|
+
zonez_sorted = numpy.sort(numpy.unique(zonez))[::-1]
|
|
887
|
+
values = numpy.zeros((nmbzones, nmbzones), dtype=config.NP_FLOAT)
|
|
888
|
+
zonez_min = numpy.min(zonez)
|
|
889
|
+
for idx, (z_upper, type_, nzone) in enumerate(zip(zonez, types_, nzones)):
|
|
890
|
+
if (type_ != ILAKE) and (z_upper > zonez_min):
|
|
891
|
+
for z_lower in zonez_sorted:
|
|
892
|
+
if z_upper > z_lower:
|
|
893
|
+
sel = (types_ != ILAKE) * (z_upper > zonez) * (zonez >= z_lower)
|
|
894
|
+
jdxs = numpy.where(sel)[0]
|
|
895
|
+
if len(jdxs) >= nzone:
|
|
896
|
+
break
|
|
897
|
+
values[idx, jdxs] = zonearea[jdxs] / numpy.sum(zonearea[jdxs])
|
|
898
|
+
return values
|
|
899
|
+
|
|
900
|
+
def verify(self) -> None:
|
|
901
|
+
"""Perform the usual parameter value verifications (implemented in method
|
|
902
|
+
|Variable.verify|) and call methods |SRed.verify_sums|, |SRed.verify_lakes|,
|
|
903
|
+
and |SRed.verify_order| for additional checks.
|
|
904
|
+
|
|
905
|
+
See the main documentation on class |SRed| for further information.
|
|
906
|
+
"""
|
|
907
|
+
super().verify()
|
|
908
|
+
self.verify_sums()
|
|
909
|
+
self.verify_lakes()
|
|
910
|
+
self.verify_order()
|
|
911
|
+
|
|
912
|
+
def verify_sums(self) -> None:
|
|
913
|
+
"""Check if the sums of all rows are either 0.0 (for dead-end zones) or 1.0
|
|
914
|
+
(for redistributing zones).
|
|
915
|
+
|
|
916
|
+
See the main documentation on class |SRed| for further information.
|
|
917
|
+
"""
|
|
918
|
+
values = self.values
|
|
919
|
+
sums = numpy.round(numpy.sum(values, axis=1), 12)
|
|
920
|
+
errors = ~numpy.isin(sums, (0.0, 1.0))
|
|
921
|
+
if numpy.any(errors):
|
|
922
|
+
raise RuntimeError(
|
|
923
|
+
f"The sum(s) of the following row(s) of parameter "
|
|
924
|
+
f"{objecttools.elementphrase(self)} are neither 0.0 nor 1.0: "
|
|
925
|
+
f"{objecttools.enumeration(numpy.where(errors)[0])}."
|
|
926
|
+
)
|
|
927
|
+
|
|
928
|
+
def verify_order(self) -> None:
|
|
929
|
+
"""Check if the weighting factors define any cycles.
|
|
930
|
+
|
|
931
|
+
See the main documentation on class |SRed| for further information.
|
|
932
|
+
"""
|
|
933
|
+
sredorder = self.subpars.pars.derived.sredorder
|
|
934
|
+
values = exceptiontools.getattr_(sredorder, "values", None)
|
|
935
|
+
try:
|
|
936
|
+
sredorder.update()
|
|
937
|
+
finally:
|
|
938
|
+
if values is not None:
|
|
939
|
+
sredorder.shape = values.shape
|
|
940
|
+
sredorder.values = values
|
|
941
|
+
|
|
942
|
+
def verify_lakes(self) -> None:
|
|
943
|
+
"""Check if any internal lake seems to be involved in snow redistribution.
|
|
944
|
+
|
|
945
|
+
See the main documentation on class |SRed| for further information.
|
|
946
|
+
"""
|
|
947
|
+
values = self.values
|
|
948
|
+
is_lake = self.subpars.zonetype.values == ILAKE
|
|
949
|
+
for axis, string in ((1, "row"), (0, "column")):
|
|
950
|
+
errors = is_lake * (numpy.sum(values, axis=axis) > 0.0)
|
|
951
|
+
if numpy.any(errors):
|
|
952
|
+
raise RuntimeError(
|
|
953
|
+
f"Internal lake zones cannot be involved in snow "
|
|
954
|
+
f"redistribution, so the sums of all {string}s of parameter "
|
|
955
|
+
f"{objecttools.elementphrase(self)} corresponding to internal "
|
|
956
|
+
f"lake zones must be zero, which is not the case for the "
|
|
957
|
+
f"{string}(s): {objecttools.enumeration(numpy.where(errors)[0])}."
|
|
958
|
+
)
|
|
959
|
+
|
|
960
|
+
@property
|
|
961
|
+
def keywordarguments(self) -> parametertools.KeywordArguments[float]:
|
|
962
|
+
"""A |KeywordArguments| object, providing the currently valid keyword argument.
|
|
963
|
+
|
|
964
|
+
We reuse one of the example configurations of the main documentation on class
|
|
965
|
+
|SRed|:
|
|
966
|
+
|
|
967
|
+
>>> from hydpy.models.hland import *
|
|
968
|
+
>>> simulationstep("12h")
|
|
969
|
+
>>> parameterstep("1d")
|
|
970
|
+
>>> nmbzones(6)
|
|
971
|
+
>>> zonetype(GLACIER, FIELD, FOREST, SEALED, ILAKE, FOREST)
|
|
972
|
+
>>> zonez(6.0, 5.0, 4.0, 3.0, 2.0, 1.0)
|
|
973
|
+
>>> zonearea.values = 1.0
|
|
974
|
+
|
|
975
|
+
After defining the values of parameter |SRed| via option `n_zones` or
|
|
976
|
+
`d_height`, the returned |KeywordArguments| object contains the given
|
|
977
|
+
name-value pair and indicates its validity by its |True|
|
|
978
|
+
|KeywordArguments.valid| attribute:
|
|
979
|
+
|
|
980
|
+
>>> sred(n_zones=1)
|
|
981
|
+
>>> sred.keywordarguments
|
|
982
|
+
KeywordArguments(n_zones=1)
|
|
983
|
+
>>> sred.keywordarguments.valid
|
|
984
|
+
True
|
|
985
|
+
|
|
986
|
+
Property |SRed.keywordarguments| checks if the last passed option still results
|
|
987
|
+
in the currently defined parameter values and sets the |KeywordArguments.valid|
|
|
988
|
+
flag to |False| if this is not the case. We show this by modifying the zone
|
|
989
|
+
heights specified by parameter |ZoneZ|:
|
|
990
|
+
|
|
991
|
+
>>> zonez(4.0, 5.0, 4.0, 3.0, 2.0, 1.0)
|
|
992
|
+
>>> sred.keywordarguments
|
|
993
|
+
KeywordArguments(n_zones=1)
|
|
994
|
+
>>> sred.keywordarguments.valid
|
|
995
|
+
False
|
|
996
|
+
|
|
997
|
+
After resetting the original values of |ZoneZ|, the |KeywordArguments.valid|
|
|
998
|
+
flag of the returned |KeywordArguments| object is |True| again:
|
|
999
|
+
|
|
1000
|
+
>>> zonez(6.0, 5.0, 4.0, 3.0, 2.0, 1.0)
|
|
1001
|
+
>>> sred.keywordarguments
|
|
1002
|
+
KeywordArguments(n_zones=1)
|
|
1003
|
+
>>> sred.keywordarguments.valid
|
|
1004
|
+
True
|
|
1005
|
+
|
|
1006
|
+
After defining the parameter values directly, the |KeywordArguments| object is
|
|
1007
|
+
always empty and invalid:
|
|
1008
|
+
|
|
1009
|
+
>>> sred(sred.values)
|
|
1010
|
+
>>> sred.keywordarguments
|
|
1011
|
+
KeywordArguments()
|
|
1012
|
+
>>> sred.keywordarguments.valid
|
|
1013
|
+
False
|
|
1014
|
+
|
|
1015
|
+
The same holds for erroneous keyword arguments:
|
|
1016
|
+
|
|
1017
|
+
>>> sred(n_zones=None)
|
|
1018
|
+
Traceback (most recent call last):
|
|
1019
|
+
...
|
|
1020
|
+
TypeError: '>=' not supported between instances of 'int' and 'NoneType'
|
|
1021
|
+
>>> sred.keywordarguments
|
|
1022
|
+
KeywordArguments()
|
|
1023
|
+
>>> sred.keywordarguments.valid
|
|
1024
|
+
False
|
|
1025
|
+
"""
|
|
1026
|
+
kwa = self._keywordarguments
|
|
1027
|
+
kwa.valid = True
|
|
1028
|
+
if len(kwa) != 1:
|
|
1029
|
+
kwa.valid = False
|
|
1030
|
+
else:
|
|
1031
|
+
for name, value in kwa:
|
|
1032
|
+
if name == "n_zones":
|
|
1033
|
+
values = self._prepare_nzones(value)
|
|
1034
|
+
else:
|
|
1035
|
+
values = self._prepare_dheight(value)
|
|
1036
|
+
if self != values:
|
|
1037
|
+
kwa.valid = False
|
|
1038
|
+
return kwa
|
|
1039
|
+
|
|
1040
|
+
def __repr__(self) -> str:
|
|
1041
|
+
keywordarguments = self.keywordarguments
|
|
1042
|
+
if keywordarguments.valid:
|
|
1043
|
+
name, value = tuple(keywordarguments)[0]
|
|
1044
|
+
return f"{self.name}({name}={objecttools.repr_(value)})"
|
|
1045
|
+
return super().__repr__()
|
|
1046
|
+
|
|
1047
|
+
|
|
1048
|
+
class TT(hland_parameters.ParameterComplete):
|
|
1049
|
+
"""Temperature threshold for snow/rain [°C]."""
|
|
1050
|
+
|
|
1051
|
+
NDIM, TYPE, TIME, SPAN = 1, float, None, (None, None)
|
|
1052
|
+
INIT = 0.0
|
|
1053
|
+
|
|
1054
|
+
|
|
1055
|
+
class TTInt(hland_parameters.ParameterComplete):
|
|
1056
|
+
"""Temperature interval with a mixture of snow and rain [°C]."""
|
|
1057
|
+
|
|
1058
|
+
NDIM, TYPE, TIME, SPAN = 1, float, None, (0.0, None)
|
|
1059
|
+
INIT = 0.0
|
|
1060
|
+
|
|
1061
|
+
|
|
1062
|
+
class DTTM(hland_parameters.ParameterLand):
|
|
1063
|
+
"""Difference between |TTM| and |TT| [°C]."""
|
|
1064
|
+
|
|
1065
|
+
NDIM, TYPE, TIME, SPAN = 1, float, None, (None, None)
|
|
1066
|
+
INIT = 0.0
|
|
1067
|
+
|
|
1068
|
+
|
|
1069
|
+
class CFMax(hland_parameters.ParameterLand):
|
|
1070
|
+
"""Average degree day factor for snow (on glaciers or not) [mm/°C/T]."""
|
|
1071
|
+
|
|
1072
|
+
NDIM, TYPE, TIME, SPAN = 1, float, True, (0.0, None)
|
|
1073
|
+
INIT = 3.5
|
|
1074
|
+
|
|
1075
|
+
|
|
1076
|
+
class CFVar(hland_parameters.ParameterLand):
|
|
1077
|
+
"""Annual variability of |CFMax| [mm/°C/T].
|
|
1078
|
+
|
|
1079
|
+
Use positive values for the northern and negative values for the southern
|
|
1080
|
+
hemisphere.
|
|
1081
|
+
"""
|
|
1082
|
+
|
|
1083
|
+
NDIM, TYPE, TIME, SPAN = 1, float, True, (None, None)
|
|
1084
|
+
INIT = 0.0
|
|
1085
|
+
|
|
1086
|
+
|
|
1087
|
+
class GMelt(hland_parameters.ParameterGlacier):
|
|
1088
|
+
"""Degree day factor for glacial ice [mm/°C/T]."""
|
|
1089
|
+
|
|
1090
|
+
NDIM, TYPE, TIME, SPAN = 1, float, True, (0.0, None)
|
|
1091
|
+
INIT = 3.5
|
|
1092
|
+
|
|
1093
|
+
|
|
1094
|
+
class GVar(hland_parameters.ParameterGlacier):
|
|
1095
|
+
"""Annual variability of |GMelt| [mm/°C/T].
|
|
1096
|
+
|
|
1097
|
+
Use positive values for the northern and negative values for the southern
|
|
1098
|
+
hemisphere.
|
|
1099
|
+
"""
|
|
1100
|
+
|
|
1101
|
+
NDIM, TYPE, TIME, SPAN = 1, float, True, (None, None)
|
|
1102
|
+
INIT = 0.0
|
|
1103
|
+
|
|
1104
|
+
|
|
1105
|
+
class CFR(hland_parameters.ParameterLand):
|
|
1106
|
+
"""Refreezing factor for water stored within the snow layer [-]."""
|
|
1107
|
+
|
|
1108
|
+
NDIM, TYPE, TIME, SPAN = 1, float, None, (0.0, None)
|
|
1109
|
+
INIT = 0.05
|
|
1110
|
+
|
|
1111
|
+
|
|
1112
|
+
class WHC(hland_parameters.ParameterLand):
|
|
1113
|
+
"""Relative water holding capacity of the snow layer [-]."""
|
|
1114
|
+
|
|
1115
|
+
NDIM, TYPE, TIME, SPAN = 1, float, None, (0.0, None)
|
|
1116
|
+
INIT = 0.1
|
|
1117
|
+
|
|
1118
|
+
|
|
1119
|
+
class FC(hland_parameters.ParameterSoil):
|
|
1120
|
+
"""Maximum soil moisture content (field capacity) [mm]."""
|
|
1121
|
+
|
|
1122
|
+
NDIM, TYPE, TIME, SPAN = 1, float, None, (0.0, None)
|
|
1123
|
+
INIT = 200
|
|
1124
|
+
|
|
1125
|
+
|
|
1126
|
+
class Beta(hland_parameters.ParameterSoil):
|
|
1127
|
+
"""Nonlinearity parameter of the soil routine [-]."""
|
|
1128
|
+
|
|
1129
|
+
NDIM, TYPE, TIME, SPAN = 1, float, None, (0.0, None)
|
|
1130
|
+
INIT = 2.0
|
|
1131
|
+
|
|
1132
|
+
|
|
1133
|
+
class PercMax(parametertools.Parameter):
|
|
1134
|
+
"""Maximum percolation rate [mm/T]."""
|
|
1135
|
+
|
|
1136
|
+
NDIM, TYPE, TIME, SPAN = 0, float, True, (0.0, None)
|
|
1137
|
+
|
|
1138
|
+
|
|
1139
|
+
class CFlux(hland_parameters.ParameterSoil):
|
|
1140
|
+
"""Capacity (maximum) of the capillary return flux [mm/T]."""
|
|
1141
|
+
|
|
1142
|
+
NDIM, TYPE, TIME, SPAN = 1, float, True, (0.0, None)
|
|
1143
|
+
INIT = 1.0
|
|
1144
|
+
|
|
1145
|
+
|
|
1146
|
+
class RespArea(parametertools.Parameter):
|
|
1147
|
+
"""Flag to enable the contributing area approach [-]."""
|
|
1148
|
+
|
|
1149
|
+
NDIM, TYPE, TIME, SPAN = 0, bool, None, (None, None)
|
|
1150
|
+
|
|
1151
|
+
|
|
1152
|
+
class RecStep(parametertools.Parameter):
|
|
1153
|
+
"""Number of internal computation steps per simulation time step [-].
|
|
1154
|
+
|
|
1155
|
+
The default value of 1440 internal computation steps per day corresponds to 1
|
|
1156
|
+
computation step per minute.
|
|
1157
|
+
|
|
1158
|
+
>>> from hydpy.models.hland import *
|
|
1159
|
+
>>> parameterstep("1d")
|
|
1160
|
+
>>> simulationstep("12h")
|
|
1161
|
+
>>> recstep(4.2)
|
|
1162
|
+
>>> recstep
|
|
1163
|
+
recstep(4.0)
|
|
1164
|
+
"""
|
|
1165
|
+
|
|
1166
|
+
NDIM, TYPE, TIME, SPAN = 0, int, True, (1, None)
|
|
1167
|
+
INIT = 1440
|
|
1168
|
+
|
|
1169
|
+
|
|
1170
|
+
class Alpha(parametertools.Parameter):
|
|
1171
|
+
"""Nonlinearity parameter of the upper zone layer [-]."""
|
|
1172
|
+
|
|
1173
|
+
NDIM, TYPE, TIME, SPAN = 0, float, None, (0.0, None)
|
|
1174
|
+
INIT = 1.0
|
|
1175
|
+
|
|
1176
|
+
|
|
1177
|
+
class K(parametertools.Parameter):
|
|
1178
|
+
"""Recession coefficient of the upper zone layer [1/T/mm^alpha].
|
|
1179
|
+
|
|
1180
|
+
In addition to the |Parameter| call method, it is possible to
|
|
1181
|
+
set the value of parameter |K| in accordance to the keyword arguments
|
|
1182
|
+
`khq`, `hq` and (optionally) `alpha`:
|
|
1183
|
+
|
|
1184
|
+
Parameter |K| allows defining its value via the keyword arguments `khq`, `hq` and
|
|
1185
|
+
(optionally) `alpha`:
|
|
1186
|
+
|
|
1187
|
+
:math:`K = \\frac{HQ}{(HQ/KHQ)^{1+Alpha}}`
|
|
1188
|
+
|
|
1189
|
+
Examples:
|
|
1190
|
+
|
|
1191
|
+
When directly setting the value of parameter |K|, one should be be aware of
|
|
1192
|
+
its time dependence:
|
|
1193
|
+
|
|
1194
|
+
>>> from hydpy.models.hland import *
|
|
1195
|
+
>>> parameterstep("1d")
|
|
1196
|
+
>>> simulationstep("12h")
|
|
1197
|
+
>>> k(2.0)
|
|
1198
|
+
>>> k
|
|
1199
|
+
k(2.0)
|
|
1200
|
+
>>> k.value
|
|
1201
|
+
1.0
|
|
1202
|
+
|
|
1203
|
+
Alternatively, one can specify the mentioned three keyword arguments:
|
|
1204
|
+
|
|
1205
|
+
>>> k(hq=10.0, khq=2.0, alpha=1.0)
|
|
1206
|
+
>>> k
|
|
1207
|
+
k(0.4)
|
|
1208
|
+
>>> k.value
|
|
1209
|
+
0.2
|
|
1210
|
+
|
|
1211
|
+
If a value for keyword argument `alpha` is missing, parameter |K| tries to
|
|
1212
|
+
query it from parameter |Alpha|.
|
|
1213
|
+
|
|
1214
|
+
>>> alpha(2.0)
|
|
1215
|
+
>>> k(hq=10.0, khq=2.0)
|
|
1216
|
+
>>> k
|
|
1217
|
+
k(0.08)
|
|
1218
|
+
>>> k.value
|
|
1219
|
+
0.04
|
|
1220
|
+
|
|
1221
|
+
The following exceptions occur for wrong combinations of keyword arguments or
|
|
1222
|
+
when |Alpha| is not ready (still has the value |numpy.nan|):
|
|
1223
|
+
|
|
1224
|
+
>>> k(wrong=1)
|
|
1225
|
+
Traceback (most recent call last):
|
|
1226
|
+
...
|
|
1227
|
+
ValueError: For parameter `k` of element `?` a value can be set directly or \
|
|
1228
|
+
indirectly by using the keyword arguments `khq` and `hq`.
|
|
1229
|
+
|
|
1230
|
+
>>> k(hq=10.0)
|
|
1231
|
+
Traceback (most recent call last):
|
|
1232
|
+
...
|
|
1233
|
+
ValueError: For the alternative calculation of parameter `k` of element `?`, \
|
|
1234
|
+
at least the keywords arguments `khq` and `hq` must be given.
|
|
1235
|
+
|
|
1236
|
+
>>> import numpy
|
|
1237
|
+
>>> alpha(numpy.nan)
|
|
1238
|
+
>>> k(hq=10.0, khq=2.0)
|
|
1239
|
+
Traceback (most recent call last):
|
|
1240
|
+
...
|
|
1241
|
+
RuntimeError: For the alternative calculation of parameter `k` of element `?`, \
|
|
1242
|
+
either the keyword argument `alpha` must be given or the value of parameter `alpha` \
|
|
1243
|
+
must be defined beforehand.
|
|
1244
|
+
|
|
1245
|
+
The default value for k of 0.009633 results from the default
|
|
1246
|
+
values for `alpha`, `hq` and `khq` given in HBV96:
|
|
1247
|
+
|
|
1248
|
+
>>> k(hq=3.0, khq=0.17, alpha=1.0)
|
|
1249
|
+
>>> k
|
|
1250
|
+
k(0.009633)
|
|
1251
|
+
"""
|
|
1252
|
+
|
|
1253
|
+
NDIM, TYPE, TIME, SPAN = 0, float, True, (0.0, None)
|
|
1254
|
+
INIT = 0.009633
|
|
1255
|
+
|
|
1256
|
+
def __call__(self, *args, **kwargs) -> None:
|
|
1257
|
+
try:
|
|
1258
|
+
super().__call__(*args, **kwargs)
|
|
1259
|
+
except NotImplementedError as exc:
|
|
1260
|
+
counter = ("khq" in kwargs) + ("hq" in kwargs)
|
|
1261
|
+
if counter == 0:
|
|
1262
|
+
raise ValueError(
|
|
1263
|
+
f"For parameter {objecttools.elementphrase(self)} a "
|
|
1264
|
+
f"value can be set directly or indirectly by using "
|
|
1265
|
+
f"the keyword arguments `khq` and `hq`."
|
|
1266
|
+
) from exc
|
|
1267
|
+
if counter == 1:
|
|
1268
|
+
raise ValueError(
|
|
1269
|
+
f"For the alternative calculation of parameter "
|
|
1270
|
+
f"{objecttools.elementphrase(self)}, at least the "
|
|
1271
|
+
f"keywords arguments `khq` and `hq` must be given."
|
|
1272
|
+
) from exc
|
|
1273
|
+
alpha = float(
|
|
1274
|
+
kwargs.get(
|
|
1275
|
+
"alpha",
|
|
1276
|
+
exceptiontools.getattr_(self.subpars.alpha, "value", numpy.nan),
|
|
1277
|
+
)
|
|
1278
|
+
)
|
|
1279
|
+
if numpy.isnan(alpha):
|
|
1280
|
+
raise RuntimeError(
|
|
1281
|
+
f"For the alternative calculation of parameter "
|
|
1282
|
+
f"{objecttools.elementphrase(self)}, either the "
|
|
1283
|
+
f"keyword argument `alpha` must be given or the value "
|
|
1284
|
+
f"of parameter `alpha` must be defined beforehand."
|
|
1285
|
+
) from exc
|
|
1286
|
+
khq = float(kwargs["khq"])
|
|
1287
|
+
hq = float(kwargs["hq"])
|
|
1288
|
+
self(hq / ((hq / khq) ** (alpha + 1.0)))
|
|
1289
|
+
|
|
1290
|
+
|
|
1291
|
+
class SGR(hland_parameters.ParameterUpperZone):
|
|
1292
|
+
"""Threshold content of |SUZ| for the generation of surface runoff [mm]."""
|
|
1293
|
+
|
|
1294
|
+
NDIM, TYPE, TIME, SPAN = 1, float, None, (0.0, None)
|
|
1295
|
+
|
|
1296
|
+
|
|
1297
|
+
class K0(hland_parameters.ParameterUpperZone):
|
|
1298
|
+
"""Storage time for surface runoff [T]."""
|
|
1299
|
+
|
|
1300
|
+
NDIM, TYPE, TIME, SPAN = 1, float, False, (None, None)
|
|
1301
|
+
|
|
1302
|
+
# defined at the bottom of the file:
|
|
1303
|
+
CONTROLPARAMETERS: tuple[type[K1]]
|
|
1304
|
+
|
|
1305
|
+
def trim(self, lower=None, upper=None) -> bool:
|
|
1306
|
+
r"""Trim |K0| following :math:`K^* \leq K0 \leq K1` with
|
|
1307
|
+
:math:`K^* = -1/ln \left( 1 - e^{-1 / k1} \right)`.
|
|
1308
|
+
|
|
1309
|
+
The additional restriction :math:`K^*` serves to prevent the storage |SUZ|
|
|
1310
|
+
from taking on negative values (see `issue 67`_).
|
|
1311
|
+
|
|
1312
|
+
>>> from hydpy.models.hland import *
|
|
1313
|
+
>>> simulationstep("1d")
|
|
1314
|
+
>>> parameterstep("1h")
|
|
1315
|
+
>>> nmbzones(5)
|
|
1316
|
+
>>> zonetype(FIELD)
|
|
1317
|
+
>>> k1(48.0, 48.0, 48.0, 48.0, nan)
|
|
1318
|
+
>>> k0(24.0, 36.0, 48.0, 72.0, 72.0)
|
|
1319
|
+
>>> k0
|
|
1320
|
+
k0(25.730308, 36.0, 48.0, 48.0, 72.0)
|
|
1321
|
+
"""
|
|
1322
|
+
if lower is None:
|
|
1323
|
+
try:
|
|
1324
|
+
lower = -1.0 / numpy.log(1.0 - numpy.exp(-1.0 / self.subpars.k1.values))
|
|
1325
|
+
except exceptiontools.AttributeNotReady:
|
|
1326
|
+
lower = 0.0
|
|
1327
|
+
if upper is None:
|
|
1328
|
+
upper = exceptiontools.getattr_(self.subpars.k1, "value", None)
|
|
1329
|
+
return super().trim(lower, upper)
|
|
1330
|
+
|
|
1331
|
+
|
|
1332
|
+
class H1(hland_parameters.ParameterUpperZone):
|
|
1333
|
+
"""Outlet level of the reservoir for simulating surface flow [mm]."""
|
|
1334
|
+
|
|
1335
|
+
NDIM, TYPE, TIME, SPAN = 1, float, None, (0.0, None)
|
|
1336
|
+
|
|
1337
|
+
|
|
1338
|
+
class TAb1(hland_parameters.ParameterUpperZone):
|
|
1339
|
+
"""Recession coefficient for simulating surface flow [T]."""
|
|
1340
|
+
|
|
1341
|
+
NDIM, TYPE, TIME, SPAN = 1, float, False, (0.0, None)
|
|
1342
|
+
|
|
1343
|
+
|
|
1344
|
+
class TVs1(hland_parameters.ParameterUpperZone):
|
|
1345
|
+
"""Recession coefficient for simulating percolation from the surface flow module
|
|
1346
|
+
[T]."""
|
|
1347
|
+
|
|
1348
|
+
NDIM, TYPE, TIME, SPAN = 1, float, False, (0.0, None)
|
|
1349
|
+
|
|
1350
|
+
|
|
1351
|
+
class K1(hland_parameters.ParameterUpperZone):
|
|
1352
|
+
"""Storage time for interflow [T]."""
|
|
1353
|
+
|
|
1354
|
+
NDIM, TYPE, TIME, SPAN = 1, float, False, (None, None)
|
|
1355
|
+
|
|
1356
|
+
# defined at the bottom of the file:
|
|
1357
|
+
CONTROLPARAMETERS: tuple[type[K0], type[K2]]
|
|
1358
|
+
FIXEDPARAMETERS = (hland_fixed.K1L,)
|
|
1359
|
+
|
|
1360
|
+
def trim(self, lower=None, upper=None) -> bool:
|
|
1361
|
+
r"""Trim |K1| following :math:`max (K0, K^*) \leq K1 \leq K2` with
|
|
1362
|
+
:math:`K^* = max \left( -1/ln \left( 1 - e^{-1 / k0} \right), K1L \right)`.
|
|
1363
|
+
|
|
1364
|
+
The additional restriction :math:`K^*` serves to prevent the storage |SUZ|
|
|
1365
|
+
from taking on negative values (see `issue 67`_).
|
|
1366
|
+
|
|
1367
|
+
>>> from hydpy.models.hland import *
|
|
1368
|
+
>>> simulationstep("1d")
|
|
1369
|
+
>>> parameterstep("1h")
|
|
1370
|
+
>>> nmbzones(9)
|
|
1371
|
+
>>> zonetype(FIELD)
|
|
1372
|
+
>>> k1(24.0, 24.0, 72.0, 120.0, 24.0, 24.0, 120.0, nan, nan)
|
|
1373
|
+
>>> k1
|
|
1374
|
+
k1(34.624681, 34.624681, 72.0, 120.0, 34.624681, 34.624681, 120.0, nan,
|
|
1375
|
+
nan)
|
|
1376
|
+
>>> k1.values = nan
|
|
1377
|
+
>>> k0(48.0, 24.0, 24.0, 24.0, nan, 24.0, nan, 24.0, nan)
|
|
1378
|
+
>>> k2(96.0, 96.0, 96.0, 96.0, nan, nan, 96.0, 96.0, nan)
|
|
1379
|
+
>>> k1(24.0, 24.0, 72.0, 120.0, 24.0, 24.0, 120.0, nan, nan)
|
|
1380
|
+
>>> k1
|
|
1381
|
+
k1(48.0, 52.324614, 72.0, 96.0, 34.624681, 52.324614, 96.0, nan, nan)
|
|
1382
|
+
"""
|
|
1383
|
+
if lower is None:
|
|
1384
|
+
k1l = self.subpars.pars.fixed.k1l.value
|
|
1385
|
+
try:
|
|
1386
|
+
lower = self.subpars.k0.values
|
|
1387
|
+
except exceptiontools.AttributeNotReady:
|
|
1388
|
+
lower = k1l
|
|
1389
|
+
else:
|
|
1390
|
+
lower = numpy.clip(
|
|
1391
|
+
lower, -1.0 / numpy.log(1.0 - numpy.exp(-1.0 / lower)), numpy.inf
|
|
1392
|
+
)
|
|
1393
|
+
lower = numpy.clip(lower, k1l, numpy.inf)
|
|
1394
|
+
lower[numpy.isnan(lower)] = k1l
|
|
1395
|
+
if upper is None:
|
|
1396
|
+
upper = exceptiontools.getattr_(self.subpars.k2, "values", None)
|
|
1397
|
+
return super().trim(lower, upper)
|
|
1398
|
+
|
|
1399
|
+
|
|
1400
|
+
class SG1Max(hland_parameters.ParameterUpperZone):
|
|
1401
|
+
"""Maximum content of the fast response groundwater reservoir |SG1| [mm]."""
|
|
1402
|
+
|
|
1403
|
+
NDIM, TYPE, TIME, SPAN = 1, float, None, (0.0, None)
|
|
1404
|
+
|
|
1405
|
+
|
|
1406
|
+
class H2(hland_parameters.ParameterUpperZone):
|
|
1407
|
+
"""Outlet level of the reservoir for simulating interflow [mm]."""
|
|
1408
|
+
|
|
1409
|
+
NDIM, TYPE, TIME, SPAN = 1, float, None, (0.0, None)
|
|
1410
|
+
|
|
1411
|
+
|
|
1412
|
+
class TAb2(hland_parameters.ParameterUpperZone):
|
|
1413
|
+
"""Recession coefficient for simulating interflow [T]."""
|
|
1414
|
+
|
|
1415
|
+
NDIM, TYPE, TIME, SPAN = 1, float, False, (0.0, None)
|
|
1416
|
+
|
|
1417
|
+
|
|
1418
|
+
class TVs2(hland_parameters.ParameterUpperZone):
|
|
1419
|
+
"""Recession coefficient for simulating percolation from the interflow module
|
|
1420
|
+
[T]."""
|
|
1421
|
+
|
|
1422
|
+
NDIM, TYPE, TIME, SPAN = 1, float, False, (0.0, None)
|
|
1423
|
+
|
|
1424
|
+
|
|
1425
|
+
class K4(parametertools.Parameter):
|
|
1426
|
+
"""Recession coefficient of the lower zone layer [1/T]."""
|
|
1427
|
+
|
|
1428
|
+
NDIM, TYPE, TIME, SPAN = 0, float, True, (0.0, None)
|
|
1429
|
+
INIT = 0.01
|
|
1430
|
+
|
|
1431
|
+
|
|
1432
|
+
class K2(hland_parameters.ParameterUpperZone):
|
|
1433
|
+
"""Storage time for quick response baseflow [T]."""
|
|
1434
|
+
|
|
1435
|
+
NDIM, TYPE, TIME, SPAN = 1, float, False, (None, None)
|
|
1436
|
+
|
|
1437
|
+
# defined at the bottom of the file:
|
|
1438
|
+
CONTROLPARAMETERS: tuple[type[K1], type[K3]]
|
|
1439
|
+
FIXEDPARAMETERS = (hland_fixed.K1L,)
|
|
1440
|
+
|
|
1441
|
+
def trim(self, lower=None, upper=None) -> bool:
|
|
1442
|
+
r"""Trim |K2| following :math:`max(K1, K1L) \leq K2 \leq K3`.
|
|
1443
|
+
|
|
1444
|
+
>>> from hydpy.models.hland import *
|
|
1445
|
+
>>> simulationstep("1d")
|
|
1446
|
+
>>> parameterstep("1h")
|
|
1447
|
+
>>> nmbzones(6)
|
|
1448
|
+
>>> zonetype(FIELD)
|
|
1449
|
+
>>> k2(12.0, 12.0, 12.0, nan, 96.0, 120.0)
|
|
1450
|
+
>>> k2
|
|
1451
|
+
k2(34.624681, 34.624681, 34.624681, nan, 96.0, 120.0)
|
|
1452
|
+
>>> k2.values = nan
|
|
1453
|
+
>>> k1(24.0, 72.0, nan, nan, nan, 72.0)
|
|
1454
|
+
>>> k3(96.0)
|
|
1455
|
+
>>> k2(12.0, 12.0, 12.0, nan, 96.0, 120.0)
|
|
1456
|
+
>>> k2
|
|
1457
|
+
k2(34.624681, 72.0, 34.624681, nan, 96.0, 96.0)
|
|
1458
|
+
"""
|
|
1459
|
+
if lower is None:
|
|
1460
|
+
k1l = self.subpars.pars.fixed.k1l.value
|
|
1461
|
+
try:
|
|
1462
|
+
lower = self.subpars.k1.values
|
|
1463
|
+
except exceptiontools.AttributeNotReady:
|
|
1464
|
+
lower = k1l
|
|
1465
|
+
else:
|
|
1466
|
+
lower[numpy.isnan(lower)] = k1l
|
|
1467
|
+
lower = numpy.clip(lower, k1l, numpy.inf)
|
|
1468
|
+
if upper is None:
|
|
1469
|
+
upper = exceptiontools.getattr_(self.subpars.k3, "value", None)
|
|
1470
|
+
return super().trim(lower, upper)
|
|
1471
|
+
|
|
1472
|
+
|
|
1473
|
+
class K3(parametertools.Parameter):
|
|
1474
|
+
"""Storage time for delayed baseflow [T]."""
|
|
1475
|
+
|
|
1476
|
+
NDIM, TYPE, TIME, SPAN = 0, float, False, (1.0, None)
|
|
1477
|
+
|
|
1478
|
+
CONTROLPARAMETERS = (K2,)
|
|
1479
|
+
FIXEDPARAMETERS = (hland_fixed.K1L,)
|
|
1480
|
+
|
|
1481
|
+
def trim(self, lower=None, upper=None) -> bool:
|
|
1482
|
+
r"""Trim |K3| in accordance with :math:`max(K2, K1L) \leq K3`.
|
|
1483
|
+
|
|
1484
|
+
>>> from hydpy.models.hland import *
|
|
1485
|
+
>>> simulationstep("1d")
|
|
1486
|
+
>>> parameterstep("1h")
|
|
1487
|
+
>>> nmbzones(3)
|
|
1488
|
+
>>> k3(12.0)
|
|
1489
|
+
>>> k3
|
|
1490
|
+
k3(34.624681)
|
|
1491
|
+
>>> k3.values = nan
|
|
1492
|
+
>>> k2(36.0, 36.0, nan)
|
|
1493
|
+
>>> k2.value[0] /= 3.0
|
|
1494
|
+
>>> k3(12.0)
|
|
1495
|
+
>>> k3
|
|
1496
|
+
k3(36.0)
|
|
1497
|
+
>>> k2.values[1] /= 3.0
|
|
1498
|
+
>>> k3(12.0)
|
|
1499
|
+
>>> k3
|
|
1500
|
+
k3(34.624681)
|
|
1501
|
+
"""
|
|
1502
|
+
if lower is None:
|
|
1503
|
+
k1l = self.subpars.pars.fixed.k1l.value
|
|
1504
|
+
try:
|
|
1505
|
+
with warnings.catch_warnings():
|
|
1506
|
+
warnings.filterwarnings("error")
|
|
1507
|
+
lower = numpy.nanmax(self.subpars.k2.values)
|
|
1508
|
+
except (exceptiontools.AttributeNotReady, RuntimeWarning):
|
|
1509
|
+
lower = k1l
|
|
1510
|
+
else:
|
|
1511
|
+
if not k1l < lower:
|
|
1512
|
+
lower = k1l
|
|
1513
|
+
return super().trim(lower, upper)
|
|
1514
|
+
|
|
1515
|
+
|
|
1516
|
+
class Gamma(parametertools.Parameter):
|
|
1517
|
+
"""Nonlinearity parameter of the lower zone layer [-]."""
|
|
1518
|
+
|
|
1519
|
+
NDIM, TYPE, TIME, SPAN = 0, float, None, (0.0, None)
|
|
1520
|
+
|
|
1521
|
+
|
|
1522
|
+
class MaxBaz(parametertools.Parameter):
|
|
1523
|
+
"""Base length of the triangle unit hydrograph [T]."""
|
|
1524
|
+
|
|
1525
|
+
NDIM, TYPE, TIME, SPAN = 0, float, False, (0.0, None)
|
|
1526
|
+
|
|
1527
|
+
|
|
1528
|
+
K0.CONTROLPARAMETERS = (K1,)
|
|
1529
|
+
K1.CONTROLPARAMETERS = (K0, K2)
|
|
1530
|
+
K2.CONTROLPARAMETERS = (K1, K3)
|