HydPy-L-Knauf (adoption of LARSIM with Knauf-based snow modelling)

One can understand lland_knauf as an extended, more complicated version of the application model lland_dd, using precipitation, temperature, wind speed, relative humidity, and actual and possible sunshine duration as meteorological input parameters. The main difference is that lland_knauf models the energy balance of snow processes in more detail (LUBW, 2006), taking not only the air temperature but also forcings like the soil heat flux or global radiation into account explicitly. This methodology includes calculating age-dependent snow albedo values, which lland_knauf can provide to actual evapotranspiration submodels as evap_aet_morsim for fine-tuning their radiation energy balance. The second difference is that lland_knauf models the soil temperature to simulate the effect of soil water freezing on runoff generation. We created lland_knauf on behalf of the German Federal Institute of Hydrology (BfG) in the context of optimising the control of the Kiel Canal (Nord-Ostsee-Kanal).

The following list summarises the main components of lland_knauf:

  • Multiple routines for adjusting the meteorological input data

  • Mixed precipitation within a definable temperature range

  • Energy balance of the snow layer after Knauf (LUBW, 2006)

  • Dynamical adjustment of the snow albedo

  • Optional refinement of the snow-surface temperature

  • Optional (re)freezing of liquid water within the snow layer

  • A simple snow retention routine

  • Usage of a submodel following the AETModel_V1 interface for calculating interception evaporation, soil evapotranspiration, and water evaporation

  • Direct runoff generation based on the Xinanjiang model (Zhao, 1977)

  • Optional inclusion of a soil submodel following the SoilModel_V1 interface

  • Frost-sealing of the upper soil layer

  • One base flow, two interflow and two direct flow components

  • A freely configurable capillary rise routine

  • Options to limit the capacity of the base flow storage

  • Separate linear storages for modelling runoff concentration

  • Additional evaporation from water areas within the subcatchment

  • Optional evaporation from inflowing runoff

Some notes for LARSIM users: lland_knauf is similar to many LARSIM models used for forecasting (relying on a combination of options equivalent to the features listed above) but not identical. Often, we strive for more flexibility. One example is modifying parameter KTSchnee to control if and how lland_knauf adjusts the snow surface temperature. However, there are also differences due to technical reasons. One relevant difference is that HydPy does not include “future values” in the current simulation timestep. For example, LARSIM fills nightly gaps regarding cloudiness with the average value of the present calendar day, while lland_knauf uses the average over the 24 hours preceding the current simulation step. Hence, do not expect the results of lland_knauf and LARSIM to be identical. When switching from one model system to the other, the need to fine-tune some parameters via calibration might arise.

lland_knauf requires a submodel that complies with the RadiationModel_V1 or the RadiationModel_V4 interface and provides the time series of possible sunshine duration, actual sunshine duration, and global radiation. An obvious choice is meteo_glob_morsim, which estimates these meteorological properties according to LARSIM.

Note

Some details of lland_knauf are still under discussion and might change in the future.

Integration tests

Note

When new to HydPy, consider reading section Integration Tests first.

Many of the following integration tests are similar to those for the application model lland_dd. When there are no substantial differences, we do not repeat our explanations, so please note the respective sections of the documentation on lland_dd. Some additional tests cover structural differences between land-use types that only exist for lland_knauf; others show various possible snow-related configurations of lland_knauf. Furthermore, we perform daily and hourly tests to point out differences and ensure lland_knauf works well for different simulation step sizes.

Note that while our daily simulations always cover an entire month, our hourly simulations cover only three days, focussing on the “most interesting” part of the daily simulation. To ensure the best possible comparability, we use the same input data (we aggregated hourly values to daily values), the same parameter values (possibly adapted to the change in the time step size), and the same initial conditions (we extract the required initial conditions of the respective hourly simulation from the longer daily simulation).

daily simulation

The following general setup is identical to the one of lland_dd, except that we now start with a different period and a daily simulation time step:

>>> from hydpy import pub
>>> pub.timegrids = "1997-08-01", "1997-09-01", "1d"
>>> from hydpy.models.lland_knauf import *
>>> parameterstep("1h")
>>> from hydpy import Node, Element
>>> outlet = Node("outlet")
>>> inlet = Node("inlet")
>>> land = Element("land", inlets=inlet, outlets=outlet)
>>> land.model = model
>>> nhru(1)
>>> ft(1.0)
>>> fhru(1.0)

acre (summer)

First, we set the values of those parameters also required by the application model lland_dd (see integration test acre (summer)):

>>> lnk(ACKER)
>>> kg(0.94)
>>> kt(0.0)
>>> hinz(0.2)
>>> lai.acker_aug = 3.5
>>> tgr(0.0)
>>> trefn(0.0)
>>> tsp(4.0)
>>> pwmax(1.43)
>>> wmax(309.0)
>>> fk(199.0)
>>> pwp(119.4)
>>> kapgrenz(option="0_WMax/10")
>>> kapmax(0.08)
>>> beta(0.001/24)
>>> fbeta(1.0)
>>> rbeta(False)
>>> dmax(r_dmax=0.55)
>>> dmin(r_dmin=10.0)
>>> bsf(0.3)
>>> volbmax(inf)
>>> gsbmax(1.0)
>>> gsbgrad1(inf)
>>> gsbgrad2(inf)
>>> a1(0.0)
>>> a2(0.5)
>>> tind(0.191056)
>>> eqb(35000.0)
>>> eqi1(400.0)
>>> eqi2(400.0)
>>> eqd1(200.0)
>>> eqd2(50.0)

In contrast to the documentation on lland_dd, we set parameter NegQ to True in most examples. That means we favour negative discharge estimates over water balance errors whenever the base flow storage cannot meet the water demand of the capillary rise of groundwater into the soil:

>>> negq(True)

Next, we set the values of the parameters specific to lland_knauf, beginning with those required for the energy-accounting snow modelling approach after Knauf (LUBW, 2006):

>>> measuringheightwindspeed(10.0)
>>> wg2z.aug = -2.9
>>> p1strahl(0.5)
>>> p2strahl(1.0/35.0)
>>> p1wind(0.6)
>>> p2wind(1.0/70.0)
>>> turb0(2.0)
>>> turb1(1.6)
>>> albedo0snow(0.9)
>>> snowagingfactor(0.35)
>>> refreezeflag(True)
>>> ktschnee(inf)

Now, we set the values of the parameters controlling the frost sealing of the upper soil layer:

>>> fvf(0.3)
>>> bsff(2.0)

All integration tests performed in daily simulation steps rely on pre-calculated radiation-related data. We use the meteo_psun_sun_glob_io submodel to provide lland_knauf with this data:

>>> with model.add_radiationmodel_v4("meteo_psun_sun_glob_io") as submodel_meteo_psun_sun_glob_io:
...     pass

We select evap_aet_morsim, which implements the MORECS method with some LARSIM-specific modifications, as the submodel for calculating the different evapotranspiration components. Note that evap_aet_morsim and lland_knauf can share the same submodel instance due to them requiring the same radiation-related data and meteo_psun_sun_glob_io being a sharable submodel that complies with SharableSubmodelInterface:

>>> with model.add_aetmodel_v1("evap_aet_morsim"):
...     albedo.acker_aug = 0.24
...     cropheight.acker_aug = 0.4
...     surfaceresistance.acker = 40.0
...     emissivity(0.95)
...     averagesoilheatflux.aug = 2.9
...     soilmoisturelimit(119.4 / 309.0)
...     model.add_radiationmodel_v4(submodel_meteo_psun_sun_glob_io)

We initialise a test function object that prepares and runs the tests and prints and plots their results:

>>> from hydpy import IntegrationTest
>>> IntegrationTest.plotting_options.axis1 = inputs.nied
>>> IntegrationTest.plotting_options.axis2 = fluxes.qah
>>> test = IntegrationTest(land)
>>> test.dateformat = "%Y-%d-%m"

Due to preparing a simulation with a daily simulation step size, we only need to define the state sequences’ initial values (not the log sequences’ initial values):

>>> test.inits = ((states.inzp, 0.0),
...               (states.wats, 0.0),
...               (states.waes, 0.0),
...               (states.esnow, 0.0),
...               (states.taus, 0.0),
...               (states.ebdn, 350.0),
...               (states.bowa, 72.0),
...               (states.sdg1, 0.0),
...               (states.sdg2, 0.0),
...               (states.sig1, 0.0),
...               (states.sig2, 0.0),
...               (states.sbg, 0.0))

We prepare those input time series usually available as measurements:

>>> inputs.nied.series = (
...     13.3, 0.1, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.0, 0.0, 2.7,
...     0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 0.3, 0.0, 0.1, 10.5, 6.5, 15.0, 9.2, 0.0,
...     0.0)
>>> inputs.teml.series = (
...     16.1, 17.3, 18.9, 17.8, 18.5, 19.9, 20.8, 20.9, 22.3, 23.0, 23.1, 23.2, 23.2,
...     21.7, 20.8, 19.5, 21.0, 21.6, 21.1, 22.4, 22.5, 19.6, 20.3, 24.1, 23.7, 21.1,
...     20.9, 20.2, 16.1, 17.0, 18.2)
>>> inputs.windspeed.series = (
...     2.4, 1.6, 1.5, 2.8, 3.0, 3.5, 3.8, 3.3, 1.8, 1.9, 3.0, 2.5, 1.6, 2.7, 3.2, 1.3,
...     1.9, 2.0, 2.6, 3.6, 2.5, 2.1, 1.5, 2.2, 1.9, 2.3, 2.1, 2.6, 2.6, 2.1, 2.1)
>>> inputs.relativehumidity.series = (
...     86.2, 85.8, 82.4, 77.6, 74.9, 77.9, 73.5, 80.1, 72.9, 68.5, 68.6, 66.0, 69.0,
...     75.6, 81.4, 79.0, 75.9, 70.0, 70.3, 69.0, 62.1, 84.5, 83.6, 76.5, 76.6, 84.2,
...     85.8, 86.5, 89.6, 78.3, 78.5)
>>> model.radiationmodel.sequences.inputs.sunshineduration.series = (
...     6.3, 1.7, 4.5, 12.4, 13.9, 13.0, 13.8, 12.3, 13.1, 12.8, 13.1, 13.3, 12.7,
...     10.2, 9.4, 10.3, 11.1, 11.0, 8.5, 11.3, 12.4, 0.1, 6.7, 10.4, 6.5, 4.9, 6.6,
...     0.3, 0.1, 5.0, 3.8)
>>> aetinputs = model.aetmodel.sequences.inputs
>>> aetinputs.atmosphericpressure.series = (
...     1007.0, 1013.0, 1016.0, 1017.0, 1018.0, 1018.0, 1019.0, 1019.0, 1019.0, 1020.0,
...     1021.0, 1022.0, 1019.0, 1015.0, 1016.0, 1019.0, 1019.0, 1018.0, 1019.0, 1019.0,
...     1017.0, 1015.0, 1015.0, 1011.0, 1008.0, 1006.0, 1005.0, 1000.0, 1004.0, 1011.0,
...     1014.0)
>>> aetinputs.windspeed.series = inputs.windspeed.series
>>> aetinputs.relativehumidity.series = inputs.relativehumidity.series
>>> inlet.sequences.sim.series = 0.0

The following two input time series stem from the results of meteo_glob_morsim calculated in the daily simulation summer example, which addresses the same place and time:

>>> model.radiationmodel.sequences.inputs.possiblesunshineduration.series = (
...     15.69078473, 15.62882066, 15.56613383, 15.50275437, 15.43871163, 15.37403418,
...     15.3087498, 15.24288548, 15.17646742, 15.10952106, 15.04207104, 14.97414122,
...     14.90575471, 14.83693386, 14.76770029, 14.69807488, 14.62807779, 14.5577285,
...     14.48704578, 14.41604776, 14.34475191, 14.27317506, 14.20133345, 14.12924271,
...     14.05691791, 13.98437357, 13.91162366, 13.83868165, 13.76556053, 13.69227282,
...     13.61883057)
>>> model.radiationmodel.sequences.inputs.globalradiation.series = (
...     190.2514903, 127.6607822, 164.4012978, 269.0205016, 287.8486672, 274.6742631,
...     284.0478917, 262.9712633, 272.2564135, 267.0192178, 269.6265466, 270.8782909,
...     261.6971638, 227.9621155, 216.3563213, 226.6379036, 235.5285025, 232.8494284,
...     199.7134896, 233.7719021, 246.1212861, 90.58551, 171.9449932, 216.5498126,
...     166.9168296, 145.9856109, 165.5438903, 87.6933456, 84.356885, 142.3092025,
...     126.7220785)

The following results illustrate the behaviour of lland_knauf for relatively dry and hot summer condions. Compared to the result table of integration test acre (summer) of the application model lland_dd, there are many more columns because of to the higher number of input, flux, and state sequences. These are mainly due to the increased data requirements and the more complex calculations of the Knauf (LUBW, 2006) approach. Therefore, lland_knauf calculates some “daily values”, representing the averages or sums over the last 24 hours:

>>> parameters.update()
>>> test.reset_inits()
>>> conditions = model.conditions
>>> conditions_acker_summer = test(
...     "lland_knauf_acker_summer_daily",
...     axis1=(inputs.nied, fluxes.qah), axis2=states.bowa,
...     get_conditions="1997-08-03")
Click to see the table
Click to see the graph

There is no indication of an error in the water balance:

>>> from hydpy import round_
>>> round_(model.check_waterbalance(conditions))
0.0

acre (routing)

The following calculation shows the possibility of routing inflowing runoff, discussed in the documentation of lland_dd:

>>> inlet.sequences.sim.series = 0.02
>>> test("lland_knauf_acker_routing_daily",
...      axis1=(inputs.nied, fluxes.qah), axis2=states.bowa)
Click to see the table
Click to see the graph

There is no indication of an error in the water balance:

>>> round_(model.check_waterbalance(conditions))
0.0

acre (heavy rain)

Integration test acre (summer) deals with dry summer conditions. To show how lland_knauf works for warm but wet conditions, we set the precipitation input time series constantly to 20 mm. Now, the soil water content (BoWa) rises from its initial value of 72 mm and nearly reaches its maximum value of 309 mm (WMax), resulting in a relevant response of all runoff components:

>>> inlet.sequences.sim.series = 0.0
>>> nied = inputs.nied.series.copy()
>>> inputs.nied.series = 20.0
>>> conditions_acker_heavy_rain = test(
...     "lland_knauf_acker_heavy_rain_daily",
...     axis1=(inputs.nied, fluxes.qah), axis2=states.bowa,
...     get_conditions="1997-08-03")
Click to see the table
Click to see the graph

There is no indication of an error in the water balance:

>>> round_(model.check_waterbalance(conditions))
0.0

acre (GARTO)

One can pep up lland_knauf with submodels following the SoilModel_V1 interface for the reasons discussed in the acre (GARTO) example of application model lland_dd. As in the acre (GARTO) example, we prepare a ga_garto_submodel1 model and assume loam soil for illustration. for illustration. We set the soil depth in agreement with the maximum soil water content (309.0 mm) and the initial relative soil moisture in agreement with the initial water content (72 mm) of the previous acre (heavy rain) example:

>>> from hydpy import pub
>>> with model.add_soilmodel_v1("ga_garto_submodel1"):
...     nmbbins(4)
...     with pub.options.parameterstep("1m"):
...         dt(1.0)
...     sealed(False)
...     soildepth(309.0 / 0.434)
...     residualmoisture(0.027)
...     saturationmoisture(0.434)
...     saturatedconductivity(13.2)
...     poresizedistribution(0.252)
...     airentrypotential(111.5)
...     states.moisture = 72.0 / 309.0 * 0.434
...     states.frontdepth = 0.0
...     states.moisturechange = 0.0

When comparing the lland_dd examples acre (summer) and acre (GARTO), we see an increase in direct runoff generation due to including infiltration excess when using ga_garto_submodel1. However, comparing the following results with the acre (heavy rain) example, we see a decrease in direct runoff generation. This behaviour results from the lower rainfall rates, which never exceed the soil’s (saturated) conductivity. Hence, ga_garto_submodel1 always lets the surface water supplied by lland_knauf infiltrate and creates no additional direct runoff component. But, starting from August 13, it calculates extra groundwater recharge. At this time, the (partly saturated) wetting front reaches the soil’s bottom and enables the continuous percolation of all rainfall through the soil column:

>>> test("lland_knauf_acker_garto_daily",
...      axis1=(inputs.nied, fluxes.qah), axis2=states.bowa)
Click to see the table
Click to see the graph

There is no indication of an error in the water balance:

>>> round_(model.check_waterbalance(conditions))
0.0
>>> del model.soilmodel
>>> inputs.nied.series = nied

water

HydPy-L defines three types of water areas, WASSER, FLUSS, and SEE. lland_knauf calculates their evaporation based on the same submodel interface as lland_dd. So, please read the detailed discussions in integration test water to better understand the following test results for water type WASSER:

>>> lnk(WASSER)
>>> negq(False)
>>> model.aetmodel.parameters.control.surfaceresistance.wasser_aug = 0.0
>>> model.aetmodel.parameters.control.cropheight.wasser_aug = 0.05
>>> model.aetmodel.parameters.control.albedo.wasser_aug = 0.7
>>> conditions_wasser = test(
...     "lland_knauf_wasser_daily",
...     axis1=(fluxes.nkor, fluxes.evi, fluxes.qah),
...     get_conditions="1997-08-03")
Click to see the table
Click to see the graph

There is no indication of an error in the water balance:

>>> round_(model.check_waterbalance(conditions))
0.0

water (routing)

The following calculation shows the possibility of subtracting evaporation from inflowing runoff, discussed in the integration test water (routing) of lland_dd:

>>> inlet.sequences.sim.series = 0.02
>>> test("lland_knauf_wasser_routing_daily",
...      axis1=(fluxes.nkor, fluxes.evi, fluxes.qah))
Click to see the table
Click to see the graph

There is no indication of an error in the water balance:

>>> round_(model.check_waterbalance(conditions))
0.0

water (negative runoff)

The following calculation shows the possibility of calculating negative discharge values, discussed in the integration test water (negative runoff) of lland_dd:

>>> negq(True)
>>> inlet.sequences.sim.series = 0.0
>>> test("lland_knauf_wasser_negq_daily",
...      axis1=(fluxes.nkor, fluxes.evi, fluxes.qah))
Click to see the table
Click to see the graph

There is no indication of an error in the water balance:

>>> round_(model.check_waterbalance(conditions))
0.0

lakes

The following example focuses on water-type SEE (for further information, see integration test lakes of lland_dd):

>>> lnk(SEE)
>>> model.aetmodel.parameters.control.surfaceresistance.see_aug = 0.0
>>> model.aetmodel.parameters.control.cropheight.see_aug = 0.05
>>> model.aetmodel.parameters.control.albedo.see_aug = 0.7
>>> negq(False)
>>> test("lland_knauf_see_daily",
...      axis1=(fluxes.nkor, fluxes.evi, fluxes.qah))
Click to see the table
Click to see the graph

There is no indication of an error in the water balance:

>>> round_(model.check_waterbalance(conditions))
0.0

streams

The following example focuses on water-type FLUSS (for further information, see integration test streams of lland_dd):

>>> lnk(FLUSS)
>>> model.aetmodel.parameters.control.surfaceresistance.fluss_aug = 0.0
>>> model.aetmodel.parameters.control.cropheight.fluss_aug = 0.05
>>> model.aetmodel.parameters.control.albedo.fluss_aug = 0.7
>>> test("lland_knauf_fluss_daily",
...       axis1=(fluxes.nkor, fluxes.evi, fluxes.qah))
Click to see the table
Click to see the graph

There is no indication of an error in the water balance:

>>> round_(model.check_waterbalance(conditions))
0.0

sealed surfaces

As also shown in the integration test sealed surfaces of lland_dd, sealed surfaces route the not intercepted water to the linear storages for direct discharge immediately:

>>> lnk(VERS)
>>> negq(True)
>>> model.aetmodel.parameters.control.surfaceresistance.vers_aug = 500
>>> model.aetmodel.parameters.control.cropheight.vers_aug = 5.0
>>> model.aetmodel.parameters.control.albedo.vers_aug = 0.10
>>> lai.vers_aug = 10.0
>>> model.aetmodel.parameters.control.leafareaindex.vers_aug = 10.0
>>> test("lland_knauf_vers_daily",
...      axis1=(inputs.nied, fluxes.qah, states.bowa))
Click to see the table
Click to see the graph

There is no indication of an error in the water balance:

>>> round_(model.check_waterbalance(conditions))
0.0

acre (winter)

None of the examples discussed so far dealt with snow processes. Thus, we now switch from a warm August to a snowy December and adapt the initial conditions and the input time series accordingly (those of global radiation and the astronomically possible sunshine duration stem from the example daily simulation winter of meteo_glob_morsim):

>>> pub.timegrids = "2010-12-01", "2011-01-01", "1d"
>>> lnk(ACKER)
>>> model.aetmodel.parameters.control.cropheight.acker_dec = 0.05
>>> model.aetmodel.parameters.control.albedo.acker_dec = 0.1
>>> lai.acker_dec = 0.3
>>> model.aetmodel.parameters.control.leafareaindex.acker_dec = 0.3
>>> wg2z.dec = 8.6
>>> model.aetmodel.parameters.control.averagesoilheatflux.dec = -8.6
>>> test = IntegrationTest(land)
>>> test.dateformat = "%Y-%d-%m"
>>> test.inits = ((states.inzp, 0.0),
...               (states.wats, 0.0),
...               (states.waes, 0.0),
...               (states.esnow, 0.0),
...               (states.taus, 0.0),
...               (states.ebdn, 0.0),
...               (states.bowa, 72.0),
...               (states.sdg1, 0.0),
...               (states.sdg2, 0.0),
...               (states.sig1, 0.0),
...               (states.sig2, 0.0),
...               (states.sbg, 0.0))
>>> inputs.nied.series = (
...     0.0, 11.1, 0.4, 1.2, 6.4, 0.0, 0.0, 0.0, 0.7, 3.3, 9.4, 0.2, 2.9, 0.0, 0.0,
...     6.7, 0.0, 0.1, 0.0, 0.2, 0.2, 2.4, 7.0, 0.2, 0.0, 1.2, 0.9, 0.0, 0.0, 0.2, 0.9)
>>> inputs.teml.series = (
...     -5.8, -3.0, -5.6, -3.8, 0.2, -1.1, -2.9, -2.9, -2.1, -3.1, 5.1, 0.2, -3.5,
...     -3.9, -6.3, -3.5, -7.3, -5.8, -7.9, -5.7, -5.6, -4.8, -1.1, -2.9, -9.1, -8.6,
...     -5.3, -7.7, -9.2, -7.4, 1.7)
>>> inputs.windspeed.series = (
...     6.9, 5.2, 2.0, 4.3, 4.0, 2.4, 1.9, 1.8, 2.7, 3.0, 7.4, 5.7, 2.2, 3.1, 2.8, 3.7,
...     0.9, 1.3, 1.9, 2.4, 2.3, 4.6, 8.6, 7.6, 3.8, 1.5, 1.3, 3.0, 2.7, 1.4, 4.2)
>>> inputs.relativehumidity.series = (
...     70.3, 85.0, 95.9, 90.6, 96.5, 99.0, 99.2, 99.1, 96.9, 95.0, 90.6, 78.7, 90.5,
...     88.1, 92.8, 98.1, 96.6, 97.7, 95.8, 97.5, 95.0, 93.8, 94.9, 85.4, 87.2, 92.7,
...     97.8, 95.4, 94.9, 96.0, 96.5)
>>> model.radiationmodel.sequences.inputs.sunshineduration.series = (
...     3.5, 0.0, 0.1, 3.7, 0.0, 0.1, 0.0, 0.0, 4.4, 0.1, 0.2, 0.7, 0.0, 1.2, 3.0, 0.0,
...     0.0, 0.0, 0.0, 0.2, 0.8, 0.0, 0.0, 0.0, 3.2, 4.3, 0.0, 3.4, 0.0, 0.0, 4.0)
>>> aetinputs.atmosphericpressure.series = (
...     1015.0, 1007.0, 1005.0, 1008.0, 996.0, 998.0, 1004.0, 1006.0, 1009.0, 1018.0,
...     1004.0, 1012.0, 1020.0, 1025.0, 1023.0, 1000.0, 991.0, 997.0, 997.0, 997.0,
...     1004.0, 1007.0, 1004.0, 1008.0, 1018.0, 1019.0, 1017.0, 1022.0, 1024.0, 1021.0,
...     1016.0)
>>> aetinputs.windspeed.series = inputs.windspeed.series
>>> aetinputs.relativehumidity.series = inputs.relativehumidity.series
>>> inlet.sequences.sim.series = 0.0
>>> model.radiationmodel.sequences.inputs.possiblesunshineduration.series = (
...     7.64102946, 7.6096444, 7.57982377, 7.55159603, 7.52498861, 7.50002776,
...     7.47673851, 7.45514453, 7.43526809, 7.41712991, 7.40074913, 7.38614323,
...     7.3733279, 7.36231706, 7.35312273, 7.34575502, 7.34022207, 7.33653002,
...     7.33468296, 7.33468296, 7.33653002, 7.34022207, 7.34575502, 7.35312273,
...     7.36231706, 7.3733279, 7.38614323, 7.40074913, 7.41712991, 7.43526809,
...     7.45514453)
>>> model.radiationmodel.sequences.inputs.globalradiation.series = (
...     31.9427981, 9.8738984, 16.6834998, 31.8074275, 9.5325105, 16.1414844,
...     9.3414287, 9.2567644, 33.405815, 15.5911584, 15.8915442, 17.8235189, 8.941324,
...     19.6680679, 26.8315815, 8.8377384, 8.817416, 8.8041854, 8.7980439, 15.4647459,
...     17.8795412, 8.8221612, 8.8443961, 8.8737425, 27.7596417, 32.3287553, 9.0045823,
...     28.9823209, 9.1276454, 9.1999895, 32.0622345)

When comparing the following results with those of integration test acre (winter) on lland_dd, it is not immediately clear what differences are due to the much higher complexities of the snow module of lland_knauf. But, at least, one can see that lland_knauf allows for the (re)freezing of liquid water within the snow layer. Refreezing occurs around December 7, where the frozen water equivalent (WATS) grows until it reaches to total water equivalent (WAeS) (a note for LARSIM users: currently, LARSIM does not implement such a freezing feature; you can disable it in lland_knauf through setting RefreezeFlag to False):

>>> test.reset_inits()
>>> conditions = model.conditions
>>> conditions_acker_winter = test(
...     "lland_knauf_acker_winter_daily",
...     axis1=(inputs.nied, fluxes.wada), axis2=(states.waes, states.wats),
...     get_conditions="2010-12-10")
Click to see the table
Click to see the graph

There is no indication of an error in the water balance:

>>> round_(model.check_waterbalance(conditions))
0.0

conifers (winter)

Next, we repeat the integration test acre (winter) but select the land use type NADELW instead of ACKER. Like for LAUBW and MISCHW, lland_knauf now modifies the global radiation, the net longwave radiation, and the wind speed to take the shadowing effects of the tree canopies into account. Here, the net effect of these modifications is that the total water equivalent’s peak amounts are two to three times smaller than for land use type ACKER. Also, snow evaporation (EvS) coincides with interception (EvI) and soil evaporation (EvB), which never happens at non-forest sites, but this is a feature evap_aet_morsim, not of lland_knauf:

>>> lnk(NADELW)
>>> model.aetmodel.parameters.control.surfaceresistance.nadelw = 56.0
>>> model.aetmodel.parameters.control.cropheight.nadelw = 10.0
>>> model.aetmodel.parameters.control.albedo.nadelw = 0.12
>>> lai.nadelw = 11.0
>>> model.aetmodel.parameters.control.leafareaindex.nadelw = 11.0
>>> conditions_nadelw_winter = test(
...     "lland_knauf_nadelw_winter_daily",
...     axis1=(inputs.nied, fluxes.wada), axis2=(states.waes, states.wats),
...     get_conditions="2010-12-10")
Click to see the table
Click to see the graph

There is no indication of an error in the water balance:

>>> round_(model.check_waterbalance(conditions))
0.0

acre (snow surface temperature)

In integration test acre (winter), lland_knauf assumes that the snow layer has a constant temperature over its complete depth. For less simplified modelling of the processes within the snow layer, one can enable an iterative adjustment of the snow surface temperature (see method Return_TempSSurface_V1). Therefore, one must set the thermal conductivity of the top snow layer (KTSchnee) to a value smaller than inf. The lower the conductivity, the higher the possible differences between the bulk and the surface temperature of the snow layer. Setting it to zero (which is not advisable) would prevent any thermal exchange. Setting it to inf results in an infinitely fast exchange, avoiding any temperature differences within the snow layer.

We show what happens when we use the default KTSchnee value used by LARSIM. In integration test acre (winter), with \(KTSchnee = inf\), nearly the complete frozen water equivalent melts on December 11, when the average air temperature is 5 °C. In our next test, with \(KTSchnee = 5 W/m²/K\), the limited thermal conductivity of the top snow layer weakens the energy flux into the snow layer and fewer snow melts. The snow surface temperature rises faster than the bulk temperature, and the higher surface temperature results in smaller sensible (WSensSnow) and latent (WLatSnow) heat fluxes from the atmosphere into the snow layer and larger longwave radiation losses (NetLongwaveRadiationSnow):

>>> lnk(ACKER)
>>> ktschnee(5.0)
>>> conditions_acker_winter_ktschnee = test(
...     "lland_knauf_acker_winter_ktschnee_daily",
...     axis1=(inputs.nied, fluxes.wada), axis2=(states.waes, states.wats),
...     get_conditions="2010-12-10")
Click to see the table
Click to see the graph

There is no indication of an error in the water balance:

>>> round_(model.check_waterbalance(conditions))
0.0
>>> ktschnee(inf)

hourly simulation

We change the simulation time step size from one day to one hour. Consequently, we need to change the values of all time-dependent control parameters by the factor 1/24 (or, in single cases, 24). Also, we need to restore() all time-dependent fixed parameter values:

>>> pub.timegrids = "1997-08-03", "1997-08-06", "1h"
>>> for parameter in control:
...     if parameter.TIME == True:
...         parameter.value = parameter.value/24
...     if parameter.TIME == False:
...         parameter.value = parameter.value*24
>>> for parameter in fixed:
...     parameter.restore()
>>> for parameter in model.aetmodel.parameters.fixed:
...     parameter.restore()

For all integration tests performed in hourly simulation steps, we switch to calculating the radiation-related data on the fly using submodel meteo_glob_morsim with parameter values taken from its documentation:

>>> with model.add_radiationmodel_v1("meteo_glob_morsim") as submodel_meteo_glob_morsim:
...     latitude(54.1)
...     longitude(9.7)
...     angstromconstant(0.25)
...     angstromfactor(0.5)
...     angstromalternative(0.15)

As meteo_psun_sun_glob_io, meteo_glob_morsim complies with SharableSubmodelInterface and is hence “sharable”:

>>> model.aetmodel.add_radiationmodel_v1(submodel_meteo_glob_morsim)
>>> test = IntegrationTest(land)

acre (summer)

The following input values agree with the ones of the respective sub-period of the daily integration test acre (summer) (global radiation and possible sunshine duration stem from hourly simulation summer):

>>> inputs.nied.series = 0.0
>>> inputs.teml.series = (
...     16.9, 16.6, 16.4, 16.3, 16.0, 15.9, 16.0, 16.6, 17.4, 19.0, 20.3, 21.4, 21.3,
...     21.8, 22.9, 22.7, 22.5, 21.9, 21.4, 20.7, 19.4, 17.8, 17.0, 16.4, 15.9, 15.4,
...     15.2, 14.9, 14.3, 14.1, 14.3, 15.4, 16.8, 18.2, 19.5, 20.3, 21.0, 21.8, 21.9,
...     21.8, 22.2, 21.8, 20.9, 19.7, 17.9, 15.8, 14.8, 14.1, 13.4, 12.8, 12.3, 12.0,
...     11.7, 11.6, 12.6, 14.8, 17.1, 19.4, 20.6, 21.4, 22.5, 23.1, 23.4, 23.8, 24.0,
...     24.0, 23.7, 22.8, 21.3, 19.3, 18.3, 17.4)
>>> inputs.windspeed.series = (
...     0.8, 0.8, 0.8, 0.8, 0.8, 0.6, 0.9, 0.9, 0.9, 1.3, 1.5, 1.2, 1.3, 1.5, 1.9, 1.9,
...     2.3, 2.4, 2.5, 2.5, 2.2, 1.7, 1.7, 2.3, 2.3, 2.2, 2.3, 2.0, 2.3, 2.5, 2.4, 2.5,
...     2.5, 2.9, 3.1, 3.3, 3.3, 3.2, 2.5, 2.9, 3.6, 4.2, 4.2, 3.6, 3.2, 2.2, 2.2, 2.1,
...     1.8, 1.8, 1.6, 1.2, 1.9, 1.3, 1.6, 1.9, 3.2, 4.0, 4.6, 4.1, 4.1, 4.4, 4.6, 4.5,
...     4.7, 4.5, 4.1, 3.8, 2.5, 1.9, 2.2, 2.7)
>>> inputs.relativehumidity.series = (
...     95.1, 94.9, 95.9, 96.7, 97.2, 97.5, 97.7, 97.4, 96.8, 86.1, 76.8, 71.8, 67.5,
...     66.1, 63.4, 62.4, 61.1, 62.1, 67.0, 74.5, 81.2, 86.9, 90.1, 90.9, 88.0, 89.2,
...     88.8, 89.7, 93.0, 93.6, 94.6, 93.3, 86.9, 78.9, 75.8, 73.4, 68.3, 61.3, 60.6,
...     58.8, 57.2, 57.2, 59.9, 66.1, 71.7, 80.6, 85.9, 89.3, 91.4, 93.1, 94.6, 95.6,
...     96.2, 95.7, 95.1, 96.3, 89.9, 79.2, 73.4, 67.3, 62.2, 59.6, 55.4, 52.1, 49.5,
...     48.1, 49.4, 57.0, 65.9, 73.0, 76.7, 81.8)
>>> model.radiationmodel.sequences.inputs.sunshineduration.series = (
...     0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2, 0.5, 0.7, 0.8, 0.5, 0.4, 0.5,
...     0.5, 0.3, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.9,
...     1.0, 1.0, 0.9, 0.8, 0.9, 0.8, 0.9, 0.9, 0.9, 1.0, 1.0, 1.0, 0.3, 0.0, 0.0, 0.0,
...     0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.6, 0.9, 1.0, 0.9, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
...     1.0, 1.0, 1.0, 1.0, 0.5, 0.0, 0.0, 0.0)
>>> aetinputs.atmosphericpressure.series = (
...     1015.0, 1015.0, 1015.0, 1015.0, 1015.0, 1015.0, 1015.0, 1015.0, 1016.0, 1016.0,
...     1016.0, 1016.0, 1016.0, 1016.0, 1016.0, 1016.0, 1016.0, 1016.0, 1016.0, 1016.0,
...     1016.0, 1016.0, 1017.0, 1017.0, 1017.0, 1016.0, 1016.0, 1016.0, 1016.0, 1017.0,
...     1017.0, 1017.0, 1017.0, 1017.0, 1017.0, 1018.0, 1018.0, 1018.0, 1018.0, 1017.0,
...     1017.0, 1017.0, 1017.0, 1017.0, 1017.0, 1018.0, 1018.0, 1018.0, 1018.0, 1018.0,
...     1018.0, 1018.0, 1018.0, 1018.0, 1018.0, 1019.0, 1019.0, 1019.0, 1019.0, 1019.0,
...     1019.0, 1019.0, 1019.0, 1019.0, 1018.0, 1018.0, 1018.0, 1018.0, 1018.0, 1018.0,
...     1018.0, 1018.0)
>>> aetinputs.windspeed.series = inputs.windspeed.series
>>> aetinputs.relativehumidity.series = inputs.relativehumidity.series
>>> inlet.sequences.sim.series = 0.0

In this and the following summer examples, we use the initial conditions of August 3rd, calculated by the corresponding daily integration tests. However, this is possible for most state sequences but not for the (now higher resolved) log sequences. Hence, we need to define them manually:

>>> test.inits = (
...     (logs.loggedsunshineduration,
...      [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2, 0.1, 0.2, 0.1, 0.2, 0.2, 0.3, 0.0,
...       0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]),
...     (logs.loggedpossiblesunshineduration,
...      [0.0, 0.0, 0.0, 0.0, 0.5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
...       1.0, 1.0, 1.0, 1.0, 1.0, 0.2, 0.0, 0.0, 0.0]),
...     (model.radiationmodel.sequences.logs.loggedunadjustedglobalradiation,
...      [0.0, 0.0, 0.0, 0.0, 0.0, 27.777778, 55.555556, 138.888889, 222.222222,
...       305.555556, 333.333333, 388.888889, 527.777778, 444.444444, 250.0,
...       222.222222, 166.666667, 111.111111, 55.555556, 27.777778, 0.0, 0.0, 0.0,
...       0.0]),
...     (model.aetmodel.sequences.logs.loggedglobalradiation,
...      [0.0, 0.0, 0.0, 0.0, 0.0, 27.8, 55.6, 138.9, 222.2, 305.6, 333.3, 388.9,
...       527.8, 444.4, 250.0, 222.2, 166.7, 111.1, 55.6, 27.8, 0.0, 0.0, 0.0, 0.0]),
...     (model.aetmodel.sequences.logs.loggedairtemperature,
...      [[13.2], [13.2], [13.1], [12.6], [12.7], [13.0], [13.5], [14.8], [16.2],
...       [17.7], [18.8], [19.4], [20.4], [21.0], [21.5], [21.2], [20.4], [20.7],
...       [20.2], [19.7], [19.0], [18.0], [17.5], [17.1]]),
...     (model.aetmodel.sequences.logs.loggedrelativehumidity,
...      [95.1, 94.5, 94.8, 96.4, 96.6, 97.1, 97.1, 96.7, 92.2, 88.5, 81.1, 76.5, 75.1,
...       70.8, 68.9, 69.2, 75.0, 74.0, 77.4, 81.4, 85.3, 90.1, 92.3, 93.8]),
...     (model.aetmodel.sequences.logs.loggedwindspeed2m,
...      [0.8, 1.0, 1.2, 1.3, 0.9, 1.1, 1.3, 1.3, 1.9, 2.2, 1.8, 2.3, 2.4, 2.5, 2.4,
...       2.5, 2.1, 2.2, 1.7, 1.7, 1.3, 1.3, 0.7, 0.8]))

ESnow and EBdn are the only state sequences with values depending on the current simulation step size. According to their unit WT/m², we must multiply their conditions saved for August 3rd and December 10th (referring to Wd/m²) by 24 (to adapt them to Wh/m²). We do so by trick to ensure we do not miss one of the relevant condition dictionaries:

>>> for key, value in locals().copy().items():
...     if key.startswith("conditions_") and ("states" in value.get("model", {})):
...         value["model"]["states"]["esnow"] *= 24
...         value["model"]["states"]["ebdn"] *= 24

This integration test deals with a dry situation. Hence, the soil water content (BoWa) shows a pronounced decline. This decline is sharpest around noon when evapotranspiration from the soil (EvB) reaches its maximum:

>>> test("lland_knauf_acker_summer_hourly",
...      axis1=(fluxes.evb, fluxes.qah), axis2=states.bowa,
...      use_conditions=conditions_acker_summer)
Click to see the table
Click to see the graph

There is no indication of an error in the water balance:

>>> round_(model.check_waterbalance(conditions_acker_summer))
0.0

acre (heavy rain)

When comparing the soil moisture content (BoWa) on August 6, 00:00, we notice only minor differences between the daily (acre (summer), 70.2 mm) and the hourly (acre (summer), 69.5) simulation results for a dry situation. However, when we compare the differences between our daily (acre (heavy rain), 152.8 mm) and our hourly test for a wet situation, we see much more pronounced differences, which are mainly due to the prioritisation of throughfall (NBes) over interception evaporation (EvI):

>>> inputs.nied.series = 20.0 / 24.0
>>> control.negq(False)
>>> test("lland_knauf_acker_heavy_rain_hourly",
...      axis1=(inputs.nied, fluxes.qah), axis2=states.bowa,
...      use_conditions=conditions_acker_heavy_rain)
Click to see the table
Click to see the graph

There is no indication of an error in the water balance:

>>> round_(model.check_waterbalance(conditions_acker_heavy_rain))
0.0

water

For our hourly integration test on water type WASSER, we deviate from the input data of the daily simulation (water) in setting precipitation to the constant value of 0.05 mm/h. The actual interception evaporation (EvI) does not show a diurnal pattern due to submodel evap_aet_morsim relying on daily aggregated input data:

>>> lnk(WASSER)
>>> inputs.nied.series = 0.05
>>> test("lland_knauf_water_hourly",
...      axis1=(fluxes.nkor, fluxes.evi, fluxes.qah),
...      use_conditions=conditions_wasser)
Click to see the table
Click to see the graph

There is no indication of an error in the water balance:

>>> round_(model.check_waterbalance(conditions))
0.0
>>> inputs.nied.series = 0.0

acre (winter)

Our hourly integration tests covering snow processes focus on the subperiod from December 10th to December 12, for which the daily simulation suggested that some melting occurs:

>>> pub.timegrids = "2010-12-10", "2010-12-13", "1h"

The following input values agree with the ones of the respective sub-period of the daily integration test acre (winter) (global radiation and possible sunshine duration stem from hourly simulation winter):

>>> inputs.nied.series = (
...     0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
...     0.1, 0.0, 0.3, 0.2, 0.4, 0.7, 0.5, 1.0, 2.0, 2.1, 1.8, 1.3, 0.5, 0.2, 0.5, 0.2,
...     0.1, 0.3, 0.1, 0.1, 0.0, 0.1, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.1,
...     0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0,
...     0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
>>> inputs.teml.series = (
...     -3.7, -4.8, -5.6, -6.2, -7.3, -8.3, -8.6, -8.5, -9.5, -9.2, -6.9, -4.0, -2.8,
...     -1.4, -0.4, 0.5, 1.0, 1.1, 1.0, 1.4, 1.6, 2.0, 2.4, 2.5, 2.7, 3.2, 3.9, 4.4,
...     4.8, 4.8, 5.1, 5.1, 5.4, 5.3, 5.5, 6.1, 6.4, 6.4, 6.5, 6.3, 5.9, 5.5, 5.1, 4.8,
...     4.9, 4.9, 4.7, 3.8, 3.9, 3.7, 3.5, 3.3, 3.3, 3.0, 1.9, 1.2, 0.8, 0.8, 0.5, 0.3,
...     -0.1, -0.4, -0.6, -0.8, -1.3, -1.6, -2.0, -2.1, -2.2, -2.6, -3.1, -3.9)
>>> inputs.windspeed.series = (
...     3.4, 2.9, 2.5, 3.0, 2.5, 2.3, 2.1, 1.4, 1.1, 1.0, 1.4, 1.3, 1.3, 1.4, 2.3, 2.8,
...     3.1, 3.5, 4.4, 3.8, 5.7, 5.6, 5.8, 6.2, 5.6, 5.2, 5.7, 6.6, 7.0, 7.3, 7.2, 7.6,
...     7.3, 7.1, 7.1, 8.9, 9.5, 7.9, 9.6, 9.1, 8.7, 8.9, 7.9, 7.1, 6.4, 7.2, 7.0, 6.8,
...     6.4, 6.3, 5.7, 5.2, 4.6, 4.9, 6.3, 5.8, 6.1, 5.9, 6.4, 6.8, 7.0, 6.3, 7.3, 7.5,
...     7.0, 6.0, 4.8, 4.2, 4.9, 4.0, 3.4, 3.4)
>>> inputs.relativehumidity.series = (
...     87.5, 90.7, 89.7, 91.3, 94.2, 93.2, 96.5, 95.9, 96.8, 94.3, 96.7, 97.4, 93.9,
...     93.4, 93.3, 94.1, 94.6, 94.4, 96.9, 98.3, 98.7, 99.6, 99.4, 99.2, 99.2, 99.6,
...     99.8, 99.8, 99.0, 97.6, 97.4, 96.3, 95.2, 96.3, 95.5, 91.6, 90.0, 85.7, 82.3,
...     82.5, 82.2, 76.5, 81.7, 83.4, 82.8, 85.8, 87.6, 85.6, 85.3, 86.2, 89.3, 91.4,
...     90.9, 89.2, 85.6, 86.3, 91.2, 87.5, 84.5, 76.7, 74.8, 69.7, 66.9, 64.4, 65.4,
...     67.6, 70.2, 70.4, 69.5, 71.6, 74.5, 80.2)
>>> model.radiationmodel.sequences.inputs.sunshineduration.series = (
...     0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0,
...     0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
...     0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
...     0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2, 0.2,
...     0.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
>>> aetinputs.atmosphericpressure.series = (
...     1017.0, 1018.0, 1018.0, 1019.0, 1020.0, 1020.0, 1021.0, 1021.0, 1022.0, 1022.0,
...     1022.0, 1022.0, 1022.0, 1021.0, 1020.0, 1020.0, 1019.0, 1018.0, 1016.0, 1015.0,
...     1014.0, 1013.0, 1011.0, 1010.0, 1008.0, 1007.0, 1006.0, 1005.0, 1005.0, 1004.0,
...     1004.0, 1004.0, 1003.0, 1003.0, 1003.0, 1002.0, 1002.0, 1002.0, 1002.0, 1003.0,
...     1003.0, 1003.0, 1003.0, 1003.0, 1003.0, 1003.0, 1003.0, 1002.0, 1002.0, 1002.0,
...     1002.0, 1003.0, 1004.0, 1005.0, 1006.0, 1008.0, 1009.0, 1010.0, 1011.0, 1012.0,
...     1013.0, 1014.0, 1015.0, 1015.0, 1017.0, 1017.0, 1018.0, 1019.0, 1019.0, 1020.0,
...     1020.0, 1020.0)
>>> aetinputs.windspeed.series = inputs.windspeed.series
>>> aetinputs.relativehumidity.series = inputs.relativehumidity.series

In this and the following winter examples, we use the initial conditions of December 10th, calculated by the corresponding daily integration tests. However, this is possible for the state sequences but not for the (now higher resolved) log sequences. Hence, we need to define them manually:

>>> test.inits = (
...     (logs.loggedsunshineduration,
...      [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.04, 0.25, 0.59, 0.91,
...       0.97, 1.0, 0.65, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]),
...     (logs.loggedpossiblesunshineduration,
...      [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.4, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
...       1.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]),
...     (model.radiationmodel.sequences.logs.loggedunadjustedglobalradiation,
...      [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 27.777778, 55.555556,
...       111.111111, 166.666667, 138.888889, 55.555556, 0.0,0.0, 0.0, 0.0, 0.0, 0.0,
...       0.0, 0.0, 0.0]),
...     (model.aetmodel.sequences.logs.loggedglobalradiation,
...      [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 27.8, 55.6, 111.1, 166.7, 138.9,
...       55.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]),
...     (model.aetmodel.sequences.logs.loggedairtemperature,
...      [[-2.8], [-2.6], [-2.2], [-1.8], [-1.8], [-2.4], [-1.5], [-1.4], [-0.8],
...       [-0.8], [-0.9], [0.9], [-0.8], [-1.0], [-1.2], [-1.8], [-2.8], [-3.8],
...       [-4.3], [-4.0], [-3.9], [-1.6], [-1.6], [2.6]]),
...     (model.aetmodel.sequences.logs.loggedrelativehumidity,
...      [99.4, 99.0, 99.6, 99.6, 99.3, 99.3, 99.8, 99.7, 100.0, 99.6, 99.3, 98.9,
...       96.6, 93.0, 91.4, 92.0, 94.5, 96.5, 98.2, 96.9, 98.0, 95.0, 91.8, 88.5]),
...     (model.aetmodel.sequences.logs.loggedwindspeed2m,
...      [2.2, 2.0, 2.5, 2.6, 2.3, 1.7, 2.8, 1.9, 2.6, 2.9, 3.5, 3.4, 3.5, 3.0, 3.9,
...       3.6, 2.2, 2.4, 2.5, 1.5, 2.5, 3.0, 3.2, 3.1]))

Compared to the daily simulation acre (winter), the hourly simulation estimates a slightly more pronounced melting rate for land-use type ACKER, resulting in a complete depletion of the snow cover:

>>> lnk(ACKER)
>>> test("lland_knauf_acker_winter_hourly",
...      axis1=(inputs.nied, fluxes.wada), axis2=(states.waes, states.wats),
...      use_conditions=conditions_acker_winter)
Click to see the table
Click to see the graph

There is no indication of an error in the water balance:

>>> round_(model.check_waterbalance(conditions_acker_winter))
0.0

conifers (winter)

By comparing the hourly simulation results for ACKER (acre (winter)) and NADELW (this example), you can see the shading effect of the tree canopies. During the nighttime, the decreased longwave radiation loss (NetLongwaveRadiationSnow) under the canopy results in an earlier start of the snow melt. But then, during the daytime, the decreased shortwave radiation gain (NetShortwaveRadiationSnow) results in a lower melting rate, so that the complete melting process finishes even later for NADELW than for ACKER:

>>> lnk(NADELW)
>>> test("lland_knauf_nadelw_winter_hourly",
...      axis1=(inputs.nied, fluxes.wada), axis2=(states.waes, states.wats),
...      use_conditions=conditions_nadelw_winter)
Click to see the table
Click to see the graph

There is no indication of an error in the water balance:

>>> round_(model.check_waterbalance(conditions_nadelw_winter))
0.0

acre (snow surface temperature)

Due to the reasons discussed in the daily integration test acre (snow surface temperature), enabling the iterative adjustment of the snow surface temperature results in a more delayed and smoothed snow melt, which becomes even more apparent in the following hourly simulation results:

>>> lnk(ACKER)
>>> ktschnee(5.0)
>>> test("lland_knauf_acker_winter_ktschnee_hourly",
...      axis1=(inputs.nied, fluxes.wada), axis2=(states.waes, states.wats),
...      use_conditions=conditions_acker_winter_ktschnee)
Click to see the table
Click to see the graph

There is no indication of an error in the water balance:

>>> round_(model.check_waterbalance(conditions_acker_winter_ktschnee))
0.0
class hydpy.models.lland_knauf.Model[source]

Bases: Main_RadiationModel_V1, Main_RadiationModel_V4, Main_AETModel_V1B, Main_SoilModel_V1, Sub_TempModel_V1, Sub_PrecipModel_V1, Sub_IntercModel_V1, Sub_SoilWaterModel_V1, Sub_SnowCoverModel_V1, Sub_SnowAlbedoModel_V1

HydPy-L-Knauf (adoption of LARSIM with Knauf-based snow modelling).

The following “inlet update methods” are called in the given sequence at the beginning of each simulation step:
  • Pick_QZ_V1 Query the current inflow from all inlet nodes.

The following “run methods” are called in the given sequence during each simulation step:
The following “outlet update methods” are called in the given sequence at the end of each simulation step:
The following interface methods are available to main models using the defined model as a submodel:
The following “additional methods” might be called by one or more of the other methods or are meant to be directly called by the user:
Users can hook submodels into the defined main model if they satisfy one of the following interfaces:
  • AETModel_V1 Interface for calculating interception evaporation, evapotranspiration from soils, evaporation from water areas in separate steps.

  • SoilModel_V1 Soil submodel interface for calculating infiltration and percolation in multiple soil compartments.

The following “submodels” might be called by one or more of the implemented methods or are meant to be directly called by the user:
  • PegasusESnow Pegasus iterator for finding the correct snow energy content.

  • PegasusTempSSurface Pegasus iterator for finding the correct snow surface temperature.

DOCNAME: DocName = ('L-Knauf', 'adoption of LARSIM with Knauf-based snow modelling')
idx_hru

The hydrological response unit index.

radiationmodel: SubmodelProperty

Required submodel that complies with one of the following interfaces: RadiationModel_V1 or RadiationModel_V4.

aetmodel: modeltools.SubmodelProperty

Required submodel that complies with the following interface: AETModel_V1.

soilmodel: modeltools.SubmodelProperty

Optional submodel that complies with the following interface: SoilModel_V1.

check_waterbalance(initial_conditions: dict[str, dict[str, dict[str, float | ndarray[Any, dtype[float64]]]]]) float[source]

Determine the water balance error of the previous simulation run in mm.

Method check_waterbalance() calculates the balance error as follows:

\[\sum_{t=t0}^{t1} \Bigg( NKor_t + QZH_t - \bigg( \sum_{k=1}^{nhru} fhru^k \cdot \Big( EvI_t^k + EvS_t^k + EvB_t^k \Big) \bigg) - QAH_t \Bigg) + \sum_{k=1}^{nhru} fhru^k \cdot \bigg( \Big( Inzp_{t0}^k - Inzp_{t1}^k \Big) + \Big( WAeS_{t0}^{k} - WAeS_{t1}^{k} \Big) + \Big( BoWa_{t0}^{k} - BoWa_{t1}^{k} \Big) \bigg) - \bigg( \Big( SDG2_{t0} - SDG2_{t1} \Big) + \Big( SDG1_{t0} - SDG1_{t1} \Big) + \Big( SIG2_{t0} - SIG2_{t1} \Big) + \Big( SIG1_{t0} - SIG1_{t1} \Big) + \Big( SBG_{t0} - SBG_{t1} \Big) \bigg)\]

The returned error should usually be in scale with numerical precision so that it does not affect the simulation results in any relevant manner. The only exception we are aware of is the “generation” of additional water when the base flow storage cannot meet the water demand required for the calculated capillary rise (see acre (capillary rise, water balance error)).

Pick the required initial conditions before starting the simulation run via property conditions. See the integration tests of the application model lland_knauf for some examples.

REUSABLE_METHODS: ClassVar[tuple[type[ReusableMethod], ...]] = ()
cymodel: CyModelProtocol | None
parameters: parametertools.Parameters
sequences: sequencetools.Sequences
masks: masktools.Masks
class hydpy.models.lland_knauf.Masks[source]

Bases: Masks

Masks applicable to lland_knauf.

The following classes are selected:
class hydpy.models.lland_knauf.AideSequences(master: Sequences, cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: AideSequences

Aide sequences of model lland_knauf.

The following classes are selected:
  • SNRatio() Ratio of frozen precipitation to total precipitation [-].

  • RLAtm() Atmosphärische Gegenstrahlung (longwave radiation emitted from the atmosphere) [W/m²].

  • TempS() Temperatur der Schneedecke (temperature of the snow layer) [°C].

class hydpy.models.lland_knauf.ControlParameters(master: Parameters, cls_fastaccess: type[FastAccessParameter] | None = None, cymodel: CyModelProtocol | None = None)

Bases: SubParameters

Control parameters of model lland_knauf.

The following classes are selected:
  • FT() Teileinzugsgebietsfläche (subbasin area) [km²].

  • NHRU() Anzahl der Hydrotope (number of hydrological response units) [-].

  • Lnk() Landnutzungsklasse (land use class) [-].

  • FHRU() Flächenanteile der Hydrotope (area percentages of the respective HRUs) [-].

  • KG() Niederschlagskorrekturfaktor (adjustment factor for precipitation) [-].

  • KT() Temperaturkorrektursummand (adjustment summand for air temperature) [°C].

  • P1Strahl() Konstante der Globalstrahlungsreduktion für Wald (constant for reducing the global radiation in forests) [-].

  • P2Strahl() Faktor der Globalstrahlungsreduktion für Wald (factor for reducing the global radiation in forests) [-].

  • Albedo0Snow() Albedo von Neuschnee (albedo of fresh snow) [-].

  • SnowAgingFactor() Wichtungsfaktor für die Sensitivität der Albedo für die Alterung des Schnees (weighting factor of albedo sensitivity for snow aging) [-].

  • Turb0() Parameter des Übergangskoeffizienten des turbulenten Wärmestroms (parameter of transition coefficient for turbulent heat flux) [W/m²/K].

  • Turb1() Parameter des Übergangskoeffizienten des turbulenten Wärmestroms (parameter of transition coefficient for turbulent heat flux) [J/m³/K].

  • MeasuringHeightWindSpeed() The height above ground of the wind speed measurements [m].

  • P1Wind() Konstante der Windgeschwindigkeitsreduktion für Wald (constant for reducing the wind speed in forests) [-].

  • P2Wind() Faktor der Windgeschwindigkeitsreduktion für Wald (factor for reducing the wind speed in forests) [-].

  • LAI() Blattflächenindex (leaf area index) [-].

  • HInz() Interzeptionskapazität bezogen auf die Blattoberfläche (interception capacity normalized to the leaf surface area) [mm].

  • TRefN() Niederschlagstemperaturgrenzwert des zur Berechnung des Wärmeeintrags durch Regen (precipitation temperature threshold to calculate heat flux caused by liquid precipitation on snow) [°C].

  • TGr() Temperaturgrenzwert flüssiger/fester Niederschlag (threshold temperature liquid/frozen precipitation) [°C].

  • TSp() Temperaturspanne flüssiger/fester Niederschlag (temperature range with mixed precipitation) [°C].

  • PWMax() Maximalverhältnis Gesamt- zu Trockenschnee (maximum ratio of the total and the frozen water equivalent stored in the snow cover) [-].

  • RefreezeFlag() Flag um wiedergefrieren zu aktivieren (flag to activate refreezing) [-].

  • KTSchnee() Effektive Wärmeleitfähigkeit der obersten Schneeschicht (effective thermal conductivity of the top snow layer) [W/m²/K].

  • WG2Z() Bodenwärmestrom in der Tiefe 2z (soil heat flux at depth 2z) [W/m²].

  • WMax() Maximaler Bodenwasserspeicher (maximum soil water storage) [mm].

  • FK() Feldkapazität / Mindestbodenfeuchte für die Interflowentstehung (field capacity / threshold value of soil moisture for interflow generation) [mm].

  • PWP() Permanenter Welkepunkt / Mindestbodenfeuchte für die Basisabflussentstehung (permanent wilting point threshold value of soil moisture for base flow generation) [mm].

  • BSf() Bodenfeuchte-Sättigungsfläche-Parameter (shape parameter for the relation between the avarage soil moisture and the relative saturated area of a subbasin) [-].

  • FVF() Frostversiegelungsfaktor zur Ermittelung des Frostversiegelungsgrades (frost sealing factor for determination of the degree of frost sealing FVG) [-].

  • BSFF() Exponent zur Ermittelung des Frostversieglungsgrades (frost sealing exponent for determination of degree of frost sealing FVG) [-].

  • DMin() Drainageindex des mittleren Bodenspeichers (flux rate for releasing interflow from the middle soil compartment) [mm/T].

  • DMax() Drainageindex des oberen Bodenspeichers (additional flux rate for releasing interflow from the upper soil compartment) [mm/T].

  • Beta() Drainageindex des tiefen Bodenspeichers (storage coefficient for releasing base flow from the lower soil compartment) [1/T].

  • FBeta() Faktor zur Erhöhung der Perkolation im Grobporenbereich (factor for increasing percolation under wet conditions) [-].

  • KapMax() Maximale kapillare Aufstiegsrate (maximum capillary rise) [mm/T].

  • KapGrenz() Grenzwerte für den kapillaren Aufstieg (threshold values related to the capillary rise) [mm].

  • RBeta() Boolscher Parameter der steuert, ob the Perkolation unterhalb der Feldkapazität auf Null reduziert wird (flag to indicate if seepage is reduced to zero below field capacity) [-].

  • VolBMax() Maximaler Inhalt des Gebietsspeichers für Basisabfluss (highest possible base flow storage) [mm].

  • GSBMax() Faktor zur Anpassung von VolBMax (factor for adjusting VolBMax) [-].

  • GSBGrad1() Höchste Volumenzunahme des Gebietsspeichers für Basisabfluss ohne Begrenzung des Zuflusses (highest possible baseflow storage increase without inflow reductions) [mm/T].

  • GSBGrad2() Volumenzunahme des Gebietsspeichers für Basisabfluss, oberhalb der jeglicher Zufluss ausgeschlossen ist (highest possible baseflow storage increase) [mm/T].

  • A1() Parameter für die kontinuierliche Aufteilung der Direktabflusskomponenten (threshold value for the continuous seperation of direct runoff in a slow and a fast component) [mm/T]

  • A2() Parameter für die diskontinuierliche Aufteilung der Direktabflusskomponenten (threshold value for the discontinuous seperation of direct runoff in a slow and a fast component) [mm/T]

  • TInd() Fließzeitindex (factor related to the time of concentration) [T].

  • EQB() Kalibrierfaktor für die Basisabflusskonzentration (factor for adjusting the concentration time of baseflow). [-].

  • EQI1() Kalibrierfaktor für die “untere” Zwischenabflusskonzentration (factor for adjusting the concentration time of the first interflow component) [-].

  • EQI2() Kalibrierfaktor für die “obere” Zwischenabflusskonzentration (factor for adjusting the concentration time of the second interflow component) [-].

  • EQD1() Kalibrierfaktor für die langsamere Direktabflusskonzentration (factor for adjusting the concentration time of the slower component of direct runoff). [-].

  • EQD2() Kalibrierfaktor für die schnellere Direktabflusskonzentration (factor for adjusting the concentration time of the faster component of direct runoff). [-].

  • NegQ() Option: sind negative Abflüsse erlaubt (flag that indicated whether negative discharge values are allowed or not) [-].

class hydpy.models.lland_knauf.DerivedParameters(master: Parameters, cls_fastaccess: type[FastAccessParameter] | None = None, cymodel: CyModelProtocol | None = None)

Bases: SubParameters

Derived parameters of model lland_knauf.

The following classes are selected:
  • MOY() References the “global” month of the year index array [-].

  • Seconds() The length of the actual simulation step size in seconds [s].

  • NmbLogEntries() The number of log entries required for a memory duration of 24 hours [-].

  • AbsFHRU() Flächen der Hydrotope (areas of the respective HRUs) [km²].

  • KInz() Interzeptionskapazität bezogen auf die Bodenoberfläche (interception capacity normalized to the soil surface area) [mm].

  • HeatOfFusion() Heat which is necessary to melt the frozen soil water content [WT].

  • Fr() Reduktionsfaktor für Strahlung according to LEG (2020) (basierend auf LUWG (2015)) (reduction factor for short- and long wave radiation) LEG (2020) (based on LUWG (2015)) [-].

  • KB() Konzentrationszeit des Basisabflusses (concentration time of the baseflow storage) [T].

  • KI1() Konzentrationszeit des “unteren” Zwischenabflusses (concentration time of the first interflow storage) [T].

  • KI2() Konzentrationszeit des “oberen” Zwischenabflusses” (concentration time of the second interflow storage) [T].

  • KD1() Konzentrationszeit des “langsamen” Direktabflusses (concentration time of the slow direct runoff storage) [T].

  • KD2() Konzentrationszeit des “schnellen” Direktabflusses (concentration time of the fast direct runoff storage) [T].

  • QFactor() Factor for converting mm/T to m³/s.

class hydpy.models.lland_knauf.FactorSequences(master: Sequences, cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: FactorSequences

Factor sequences of model lland_knauf.

The following classes are selected:
class hydpy.models.lland_knauf.FixedParameters(master: Parameters, cls_fastaccess: type[FastAccessParameter] | None = None, cymodel: CyModelProtocol | None = None)

Bases: SubParameters

Fixed parameters of model lland_knauf.

The following classes are selected:
  • CPWasser() Spezifische Wärmekapazität von Wasser (specific heat capacity of water) [WT/kg/K].

  • CPEis() Spezifische Wärmekapazität von Eis bei 0 °C (specific heat capacity of ice at a temperature of 0 °C) [WT/kg/K].

  • RSchmelz() Spezifische Schmelzwärme von Wasser (specific melt heat of water) [WT/kg].

  • Z() Halbe Mächtigkeit der in der Temperaturmodellierung betrachteten Bodensäule (the half thickness of the surface soil layer relevant for modelling soil temperature) [m].

  • BoWa2Z() Bodenwassergehalt der Bodenschicht bis zu einer Tiefe 2z (soil water content of the soil layer down two a depth of 2z) [mm].

  • LambdaG() Wärmeleitfähigkeit des Bodens (thermal conductivity of the top soil layer) [W/m/K].

  • Sigma() Stefan-Boltzmann-Konstante (Stefan-Boltzmann constant) [W/m²/K].

  • LWE() Mittlere latente Verdunstungswärme für Wasser und Eis (average heat of condensation for water and ice) [WT/kg].

  • PsyInv() Kehrwert der Psychrometerkonstante über Schnee und Eis bei 0°C (inverse psychrometric constant for ice and snow at 0°C) [K/hPa].

  • Z0() Rauhigkeitslänge für Wiese (roughness length for short grass) [m].

  • FrAtm() Empirischer Faktor zur Berechnung der atmosphärischen Gegenstrahlung (empirical factor for the calculation of atmospheric radiation) [-]

  • CG() Volumetrische Wärmekapazität des Bodens (volumetric heat capacity of soil) [WT/m³/K].

class hydpy.models.lland_knauf.FluxSequences(master: Sequences, cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: FluxSequences

Flux sequences of model lland_knauf.

The following classes are selected:
  • QZ() Zufluss in das Teilgebiet (inflow into the subcatchment) [m³/s].

  • QZH() Abflussspende in das Teilgebiet (inflow into the subcatchment) [mm/T].

  • DailySunshineDuration() Daily sunshine duration [h].

  • DailyPossibleSunshineDuration() Astronomically possible daily sunshine duration [h].

  • GlobalRadiation() Globalstrahlung (global radiation) [W/m²].

  • NKor() Korrigierter Niederschlag (corrected precipitation) [mm/T].

  • TKor() Korrigierte Lufttemperatur (corrected air temperature) [°C].

  • WindSpeed2m() Wind speed at a height of 2 m above the ground for grass [m/s].

  • ReducedWindSpeed2m() Land-use-specific wind speed at a height of 2 m above the ground [m/s].

  • SaturationVapourPressure() Saturation vapour pressure [hPa].

  • SaturationVapourPressureSnow() Saturation vapour pressure snow [hPa].

  • ActualVapourPressure() Actual vapour pressure [hPa].

  • TZ() Bodentemperatur in der Tiefe z (soil temperature at depth z) [°C].

  • WG() “Dynamischer” Bodenwärmestrom (“dynamic” soil heat flux) [W/m²].

  • NetShortwaveRadiationSnow() Kurzwellige Netto-Strahlungsbilanz für Schneeoberflächen (net shortwave radiation for snow surfaces) [W/m²].

  • NetLongwaveRadiationSnow() Net longwave radiation for snow-surfaces [W/m²].

  • NetRadiationSnow() Total net radiation for snow-surfaces [W/m²].

  • NBes() Gesamter Bestandsniederschlag (total stand precipitation) [mm/T].

  • SBes() Schneeanteil Bestandsniederschlag (frozen stand precipitation) [mm/T].

  • EvI() Tatsächliche Verdunstung von Interzeptions- und permanenten Wasserflächen (actual evaporation from interception storages and water areas) [mm/T].

  • EvB() Tatsächliche Verdunstung von Bodenwasser (actual evaporation of soil water) [mm/T].

  • EvS() Tatsächliche Schneeverdunstung (actual evaporation of snow-water) [mm/T].

  • WNied() Niederschlagsbedingter Wärmestrom in die Schneedecke (heat flux into the snow layer due to precipitation) [W/m²].

  • TempSSurface() Schneetemperatur an der Schneeoberfläche (the snow temperature at the snow surface) [°C].

  • ActualAlbedo() Aktuelle Albedo der relevanten Oberfläche (the current albedo of the relevant surface) [-].

  • SchmPot() Potentielle Schneeschmelze (potential amount of water melting within the snow cover) [mm/T].

  • Schm() Tatsächliche Schneeschmelze (actual amount of water melting within the snow cover) [mm/T].

  • GefrPot() Potentielles Schnee-Wiedergefrieren (potential amount of water refreezing within the snow cover) [mm/T].

  • Gefr() Tatsächliche Schnee-Wiedergefrieren (actual amount of water refreezing within the snow cover) [mm/T].

  • WLatSnow() Latente Wärmestrom Schnee/Atmosphäre (latent heat flux between the snow-layer and the atmosphere) [W/m²].

  • WSensSnow() Fühlbare Wärmestrom Schnee/Atmosphäre (sensible heat flux between the snow-layer and the atmosphere) [W/m²].

  • WSurf() Wärmestrom von der Schneedecke zur Schneeoberfläche (heat flux from the snow layer to the snow surface) [W/m²].

  • SFF() Relativer Anteil des gefrorenen Bodenwassers bis zu einer Tiefe von 2z (relative proportion of frozen soil water) [-].

  • FVG() Frostversiegelungsgrad (degree of frost sealing) [-].

  • WaDa() Wasserdargebot (water reaching the soil routine) [mm/T].

  • QDB() Direktabfluss-Abgabe aus dem Bodenspeicher (direct runoff release from the soil storage) [mm/T].

  • QIB1() Erste Komponente der Interflow-Abgabe aus dem Bodenspeicher (first component of the interflow release from the soil storage) [mm/T].

  • QIB2() Zweite Komponente der Interflow-Abgabe aus dem Bodenspeicher (second component of the interflow release from the soil storage) [mm/T].

  • QBB() Basisabfluss-Abgabe aus dem Bodenspeicher (base flow release from the soil storage) [mm/T].

  • QKap() Kapillarer Aufstieg in den Bodenspeicher (capillary rise to soil storage) [mm/T].

  • QDGZ() Gesamtzufluss in beide Direktabfluss-Gebietsspeicher (total inflow to both direct runoff storages) [mm/T].

  • QDGZ1() Zufluss in den trägeren Direktabfluss-Gebietsspeicher (inflow to the slow direct runoff storage) [mm/T].

  • QDGZ2() Zufluss in den dynamischeren Direktabfluss-Gebietsspeicher (inflow to the fast direct runoff storage) [mm/T].

  • QIGZ1() “Zufluss in den ersten Zwischenabfluss-Gebietsspeicher (inflow to the first interflow storage) [mm/T].

  • QIGZ2() Zufluss in den zweiten Zwischenabfluss-Gebietsspeicher (inflow to the second interflow storage) [mm/T].

  • QBGZ() Zufluss in den Basisabfluss-Gebietsspeicher (inflow to the base flow storage) [mm/T].

  • QDGA1() Abfluss aus dem trägeren Direktabfluss-Gebietsspeicher (outflow from the slow direct runoff storage) [mm/T].

  • QDGA2() Abfluss aus dem dynamischeren Direktabfluss-Gebietsspeicher (outflow from the fast direct runoff storage) [mm/T].

  • QIGA1() Abfluss aus dem “unteren” Zwischenabfluss-Gebietsspeicher (outflow from the first interflow storage) [mm/T].

  • QIGA2() Abfluss aus dem “oberen” Zwischenabfluss-Gebietsspeicher (outflow from the second interflow storage) [mm/T].

  • QBGA() Abfluss aus dem Basisabfluss-Gebietsspeicher (outflow from the base flow storage) [mm/T].

  • QAH() Abflussspende des Teilgebiets (runoff at the catchment outlet) [mm/T].

  • QA() Abfluss des Teilgebiets (runoff at the catchment outlet) [m³/s].

class hydpy.models.lland_knauf.InletSequences(master: Sequences, cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: InletSequences

Inlet sequences of model lland_knauf.

The following classes are selected:
  • Q() Abfluss (runoff) [m³/s].

class hydpy.models.lland_knauf.InputSequences(master: Sequences, cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: InputSequences

Input sequences of model lland_knauf.

The following classes are selected:
class hydpy.models.lland_knauf.LogSequences(master: Sequences, cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: LogSequences

Log sequences of model lland_knauf.

The following classes are selected:
class hydpy.models.lland_knauf.OutletSequences(master: Sequences, cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: OutletSequences

Outlet sequences of model lland_knauf.

The following classes are selected:
  • Q() Abfluss (runoff) [m³/s].

class hydpy.models.lland_knauf.StateSequences(master: Sequences, cls_fastaccess: type[TypeFastAccess_co] | None = None, cymodel: CyModelProtocol | None = None)

Bases: StateSequences

State sequences of model lland_knauf.

The following classes are selected:
  • Inzp() Interzeptionsspeicherung (interception storage) [mm].

  • WATS() Wasseräquivalent Trockenschnee auf der Bodenoberfläche (frozen water equivalent of the snow cover) [mm].

  • WAeS() Wasseräquivalent Gesamtschnee auf der Bodenoberfläche (total water equivalent of the snow cover) [mm].

  • ESnow() Thermischer Energieinhalt der Schneedecke bezogen auf 0°C (thermal energy content of the snow layer with respect to 0°C) [WT/m²].

  • TauS() Dimensionsloses Alter der Schneedecke (dimensionless age of the snow layer) [-].

  • EBdn() Energiegehalt des Bodenwassers (energy content of the soil water) [WT/m²].

  • BoWa() Bodenwasserspeicherung (soil water storage) [mm].

  • SDG1() Träger Direktabfluss-Gebietsspeicher (slow direct runoff storage) [mm].

  • SDG2() Dynamischer Direktabfluss-Gebietsspeicher (fast direct runoff storage) [mm].

  • SIG1() Erster Zwischenabfluss-Gebietsspeicher (first interflow storage) [mm].

  • SIG2() Zweiter Zwischenabfluss-Gebietsspeicher (second interflow storage) [mm].

  • SBG() Basisabfluss-Gebietsspeicher (base flow storage) [mm].