HydPy-Evap-AET-Minhas (actual evapotranspiration based on the Minhas equation)

evap_aet_minhas serves as a submodel that supplies its main model with estimates of evapotranspiration from soils and evaporation from interception storages and water areas. Therefore, it requires potential evapotranspiration data calculated by a sub-submodel. See, for example, the documentation of application model lland_dd, where evap_ret_tw2002 calculates grass reference evapotranspiration values after Turc-Wendling (ATV-DVWK, 2002), which evap_pet_mlc converts to month- and land type-specific potential evapotranspiration values.

Integration tests

Note

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

According to the intended usage as a submodel, evap_aet_minhas requires no connections to any nodes. Hence, assigning a model instance to a blank Element instance is sufficient:

>>> from hydpy import Element
>>> from hydpy.models.evap_aet_minhas import *
>>> parameterstep("1h")
>>> element = Element("element")
>>> element.model = model

We perform the integration test for three simulation days:

>>> from hydpy import IntegrationTest, pub
>>> pub.timegrids = "2000-01-01", "2000-01-04", "1d"

Besides the number of hydrological response units, which evap_aet_minhas usually receives from its main model in real applications, we only need to define values for the control parameters MaxSoilWater and DisseFactor:

>>> nmbhru(1)
>>> maxsoilwater(200.0)
>>> dissefactor(5.0)

We add submodels of type evap_ret_io, dummy_interceptedwater, and dummy_soilwater for providing pre-defined values of potential evapotranspiration (identical values for potential interception evaporation and soil evapotranspiration), intercepted water, and soil water:

>>> with model.add_petmodel_v1("evap_ret_io"):
...     hruarea(1.0)
...     evapotranspirationfactor(1.0)
>>> with model.add_intercmodel_v1("dummy_interceptedwater"):
...     pass
>>> with model.add_soilwatermodel_v1("dummy_soilwater"):
...     pass

Now, we can initialise an IntegrationTest object:

>>> test = IntegrationTest(element)
>>> test.dateformat = "%d/%m"

All of the following tests share the same input time series. Reference evapotranspiration (used as potential evapotranspiration) and the initial soil water content are identical for all three days, while the initial amount of intercepted water varies from 0 to 2 mm, of which the last value equals reference evaporation:

>>> model.petmodel.sequences.inputs.referenceevapotranspiration.series = 2.0
>>> model.intercmodel.sequences.inputs.interceptedwater.series = [[0.0], [1.0], [2.0]]
>>> model.soilwatermodel.sequences.inputs.soilwater.series = 100.0

vegetated soil

For “vegetated soils”, interception evaporation and soil evapotranspiration are relevant:

>>> interception(True)
>>> soil(True)
>>> water(False)

The results for the second day show that the sum of interception evaporation and soil water evapotranspiration never exceeds the given potential evapotranspiration:

>>> test()
Click to see the table

bare soil

Next, we assume a “bare soil” where interception processes are irrelevant:

>>> interception(False)
>>> soil(True)
>>> water(False)

Due to ignoring possible interception evaporation, soil water evapotranspiration is identical for all three days:

>>> test()
Click to see the table

sealed soil

The following “sealed soil” can evaporate water from its surface but not from its body:

>>> interception(True)
>>> soil(False)
>>> water(False)

All results are as to be expected:

>>> test()
Click to see the table

water area

A “water area” comes neither with a solid surface nor a soil body:

>>> interception(False)
>>> soil(False)
>>> water(True)

There is never any difference between potential and actual evaporation for water areas:

>>> test()
Click to see the table

unequal potential values, soil

The previous examples relied on the evap_ret_io submodel, which complies with the PETModel_V1 interface that provides only a single potential evapotranspiration value per time step. evap_aet_minhas is also compatible with submodels that follow PETModel_V2, which offers separate potential values for interception evaporation, soil evapotranspiration, and evaporation from water areas. We use evap_pet_ambav1 to demonstrate this functionality:

>>> with model.add_petmodel_v2("evap_pet_ambav1"):
...     hrutype(0)
...     plant(True)
...     measuringheightwindspeed(10.0)
...     leafalbedo(0.2)
...     leafalbedosnow(0.8)
...     groundalbedo(0.2)
...     groundalbedosnow(0.8)
...     leafareaindex(5.0)
...     cropheight(1.0)
...     leafresistance(40.0)
...     wetsoilresistance(100.0)
...     soilresistanceincrease(1.0)
...     wetnessthreshold(0.5)
...     cloudtypefactor(0.2)
...     nightcloudfactor(1.0)
...     with model.add_tempmodel_v2("meteo_temp_io"):
...         hruarea(1.0)
...         temperatureaddend(0.0)
...     with model.add_precipmodel_v2("meteo_precip_io"):
...         hruarea(1.0)
...         precipitationfactor(1.0)
...     with model.add_radiationmodel_v4("meteo_psun_sun_glob_io"):
...         pass
...     with model.add_snowcovermodel_v1("dummy_snowcover"):
...         pass

After recreating the IntegrationTest object, we can define the time series and initial conditions required by evap_pet_ambav1:

>>> test = IntegrationTest(element)
>>> test.dateformat = "%d/%m"
>>> model.petmodel.sequences.inputs.windspeed.series = 2.0
>>> model.petmodel.sequences.inputs.relativehumidity.series = 80.0
>>> model.petmodel.sequences.inputs.atmosphericpressure.series = 1000.0
>>> model.petmodel.tempmodel.sequences.inputs.temperature.series = 15.0
>>> model.petmodel.precipmodel.sequences.inputs.precipitation.series = 0.0
>>> model.petmodel.radiationmodel.sequences.inputs.sunshineduration.series = 6.0
>>> model.petmodel.radiationmodel.sequences.inputs.possiblesunshineduration.series = 16.0
>>> model.petmodel.radiationmodel.sequences.inputs.globalradiation.series = 190.0
>>> model.petmodel.snowcovermodel.sequences.inputs.snowcover.series = 0.0
>>> test.inits = (
...     (model.petmodel.sequences.states.soilresistance, 100.0),
...     (model.petmodel.sequences.logs.loggedprecipitation, [0.0]),
...     (model.petmodel.sequences.logs.loggedpotentialsoilevapotranspiration, [1.0])
... )

The time series of intercepted and soil water agree with the previous examples:

>>> model.intercmodel.sequences.inputs.interceptedwater.series = [[0.0], [1.0], [2.0]]
>>> model.soilwatermodel.sequences.inputs.soilwater.series = 100.0

The following results are comparable to the vegetated soil example. As long as (positive) potential interception evaporation is larger than (positive) potential soil evapotranspiration, the sum of actual interception evaporation and actual soil evapotranspiration should never exceed potential interception evaporation:

>>> interception(True)
>>> soil(True)
>>> water(False)
>>> test()
Click to see the table

unequal potential values, water

For water areas, evap_aet_minhas takes the potential water evaporation calculated by evap_pet_ambav1 as actual water evaporation:

>>> interception(False)
>>> soil(False)
>>> water(True)
>>> test()
Click to see the table
class hydpy.models.evap_aet_minhas.Model[source]

Bases: Main_PET_PETModel_V1, Main_PET_PETModel_V2, Main_IntercModel_V1, Main_SoilWaterModel_V1, Sub_ETModel, AETModel_V1

HydPy-Evap-AET-Minhas (actual evapotranspiration based on the Minhas equation).

The following “run methods” are called in the given sequence during 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:
  • PETModel_V1 Simple interface for calculating all potential evapotranspiration values in one step.

DOCNAME: DocName = ('Evap-AET-Minhas', 'actual evapotranspiration based on the Minhas equation')
petmodel: SubmodelProperty

Required submodel that complies with one of the following interfaces: PETModel_V1 or PETModel_V2.

intercmodel: modeltools.SubmodelProperty

Required submodel that complies with the following interface: IntercModel_V1.

soilwatermodel: modeltools.SubmodelProperty

Required submodel that complies with the following interface: SoilWaterModel_V1.

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

Bases: SubParameters

Control parameters of model evap_aet_minhas.

The following classes are selected:
  • NmbHRU() The number of separately modelled hydrological response units [-].

  • Water() A flag that indicates whether the individual zones are water areas or not.

  • Interception() A flag that indicates whether interception evaporation is relevant for the individual zones.

  • Soil() A flag that indicates whether soil evapotranspiration is relevant for the individual zones.

  • MaxSoilWater() Maximum soil water content [mm].

  • DisseFactor() Factor for calculating actual soil evapotranspiration based on potential evapotranspiration estimates that follow the Disse (1995) formulation of the Minhas et al. (1974) equation.

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

Bases: FactorSequences

Factor sequences of model evap_aet_minhas.

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

Bases: FluxSequences

Flux sequences of model evap_aet_minhas.

The following classes are selected: