Closed tyralla closed 1 year ago
Decide if we still need
evap_fao
as a stand-alone model. This is not required for usual HydPy projects (where we model the complete water balance of river catchments) but would help if we want to calculate pet time series for other purposes.
When implementing (a preliminary?) version of evap_tw
, it was easy to make it both a stand-alone model and a submodel. The trick (for an AdHocModel
) is to let the appropriate interface method just call the run
method. For example:
class Determine_PotentialEvapotranspiration_V2(modeltools.Method):
SUBMETHODS = (
Calc_AdjustedAirTemperature_V1,
Calc_ReferenceEvapotranspiration_V2,
)
CONTROLPARAMETERS = (
evap_control.NmbHRU,
evap_control.Altitude,
evap_control.CoastFactor,
evap_control.EvapotranspirationFactor,
)
REQUIREDSEQUENCES = (
evap_inputs.GlobalRadiation,
evap_inputs.AirTemperature,
)
RESULTSEQUENCES = (evap_fluxes.ReferenceEvapotranspiration,)
@staticmethod
def __call__(model: modeltools.AdHocModel) -> None:
model.run()
This helps avoid code duplications and additional tests. So, there seems to be no reason to refrain from making evap_fao
both a stand-alone model and a submodel, as well.
Decide if the evap submodels read their input data or receive (possibly adjusted) input data from the main model.
We decided on reading. See this comment in #90.
- Eventually, support letting submodels read input time series on their own
Again, see this comment in #90.
I realised only lland_v2 uses method Calc_ET0_WET0_V1 for calculating "delayed" evaporation from water bodies, but lland_v1 does not. I will add it to lland_v1 before removing lland_v2 to not lose any functionalities due to this refactoring.
- Increase the dimensionality of the already available parameter and sequence classes of evap from zero to one and adjust all equations accordingly.
Finished. Now, one can use evap_fao56
for calculating reference evapotranspiration for different hydrological response units. The only difference in the computed values stems from a temperature adjustment to (the altitude of) the individual units and, eventually, applying different evapotranspiration adjustment factors.
Also, I added evap_io
for reading reference evapotranspiration time series from files. This allowed fusing lland_v1
and lland_v2
, which is also completed (including documentation updates).
The next step is to let wland use the new reference evapotranspiration submodels. I suspected the implementation would be straightforward but encountered one nasty detail.
wland
comes with two sequences for potential evapotranspiration. PETL is 1-dimensional and contains individual values for all "land" units. PES is 0-dimensional and includes a single value for the surface water area.
I see two possible solutions:
The latter approach is definitely more flexible and, most likely, less error-prone. The additional configuration effort seems acceptable. However, this conflicts with our current assumption that each primary model instance reference only one submodel of a specific interface (see this comment in #90).
In my opinion, we should extend the general strategy of referencing submodels to make the second solution possible.
It might take some effort, but I am also convinced that that it will be worthwhile to make this possible. Especially if you think of the evaporation of the LARSIM models this distinction between potential lake and land evapotranspiration simplifies many things.
I would also prefer the 2. option, defining the first time series as wlands urface water area could lead to confusions and contradicts in my opinion the object oriented HydPy approach
The second option is implemented! And I improved a few related things so far (and switched to Python 3.11!) that I finally dared to merge into master. I need to update Travis' permissions. After that, the online documentation will also be up-to-date.
So far, we can connect the submodels evap_io
, evap_fao56
, and evap_tw2002
to all applications models derived from the base models lland
and wland
. Now it is time to extract evap_hbv96
from hland
.
All versions of hland
perform the following steps for calculating potential evapotranspiration:
EP
).EP
by multiplying it with a (possibly land-use-specific) coefficient.We already discussed some aspects, but we still need to settle our targets before I should start introducing changes.
Nowadays, it is expected to either use externally interpolated meteorological input data or let the hydrological modelling system perform the interpolation on the fly. HydPy supports both approaches. Hence, there seems no need to keep the parameters zrelt
, zrele
, and zrelp
, which are primarily thought for adjusting station data (measured at a specific elevation) to a subbasin (with a different mean elevation). If I remember correctly, we agreed to remove all these control parameters.
Instead, we could introduce a single derived parameter that automatically calculates the mean basin elevation based on the zones' elevation and size. We would then use this single parameter for adjusting the (given) basin averages of temperature, evaporation, and precipitation to the individual zones.
If we go this way, most steps are straightforward. We would move the evapotranspiration elevation adjustment factor from hland
to evap
and leave the temperature elevation adjustment factor in hland
.
However, at least one aspect needs extra consideration.
hland
has no "specific" parameter to adjust the calculated reference evapotranspiration to different zone types. There is only the parameter ECorr
, which could, for example, be used to reflect the different evapotranspiration rates of different crops but could also be configured in other manners. In contrast, lland
and wland
provide special parameters that adjust reference evapotranspiration based on crop- and month-specific factors. For consistency with our previous modularisation steps, we should move ECorr
from hland
to evap
. But then, ECorr
would not be directly connectable to the land-use types of hland
.
We could add a parameter to hland
that is similar to the mentioned ones of lland
and wland
. Or, we could move the "land-use-adjustment logic" from all main models to evap
. So far, I have no idea how, but I tend to favour the second approach. When thinking about the planned modularisation of actual evaporation processes (!!! extracting MORECS from lland
!!!), we may need to synchronise the land-use handling of main models and their submodels anyhow. Should we possibly also
standardise land-use types?
I suggest starting as described above (moving ECorr
, or, more precisely, removing it from hland
and using EvapotranspirationFactor
within evap
instead) if no one disagrees.
Maybe we can collect ideas on sharing land-use information in the meantime.
I prefer to implement some significant general submodel functionalities for sharing parameter information before continuing here. See this comment in #90.
I need to update Travis' permissions. After that, the online documentation will also be up-to-date.
There was also an issue due to pushing unnecessary, too-large files to GitHub Pages. Solved by b8a06173d4621ec1e2c208ec5d62e801a523175e. The online documentation now describes evap_io, evap_fao56, evap_tw2002, and the adjustments to HydPy-L(ARSIM) and HydPy-W(ALRUS).
We made the necessary progress to continue extraction evap_hbv96
from hland
. However, I encountered another problem or necessary decision when starting with it.
HBV96 adjusts the estimated potential evapotranspiration to the current precipitation rate (see Calc_EPC_V1). That means, we evap_hbv96
must know about the precipitation falling in the individual zones. Unfortunately, the required precipitation must also be corrected beforehand, which needs adjusting the air temperature to the heights of the respective zones.
I see the following options:
hland
and evap
. (Something we want to avoid. Also doubled runtime costs.)evap_hbv96
. (This one is my favourite. All models that need to calculate evapotranspiration also handle precipitation. We do not need a second petinterface
, as submodels that do not require precipitation data can silently ignore the given values (But maybe we would favour a second interface for clarity?). The only drawback: evap_hbv96
would not work as a stand-alone model.)If no one objects, I check if the third option is feasible.
- The only drawback:
evap_hbv96
would not work as a stand-alone model.
Just a spontaneous idea: Could we introduce a precip_io
model (similar to evap_io
)? evap_hbv96
could either take the required precipitation from a precip_io
or, and that is the idea, from its main model (by somehow handling its main model like a submodel). It is a first thought we can wait to follow. However, it would be great if something like that would work as it would simplify implementing stand-alone models and increase flexibility significantly.
evap_hbv96
now works and can query its precipitation data from its main model or a "real" submodel (see here for the technical status). However, the LahnH
example project is still out of order since I have not adopted the meteorological input series. And I think we should first allow the same mechanism for air temperature as for precipitation. First, in doing so, we would not need to duplicate huge amounts of the available input data. Second, we will likely introduce "temperature submodels" later, anyhow, which would mean we need to revert some of these changes.
It seems we are ready. I just pushed all relevant commits to master, the docs are up-to-date. The next step will be refactoring actual evapotranspiration. This might somehow influence our potential evaporation submodels, but this can be discussed in a separate issue. We can re-open this issue if we encounter any general deficits in our potential evapotranspiration models or want to think about fine-tuning parameter names or things like that.
Starting with issue #90, we introduced a new submodel concept for improving the modularisation level of the models implemented in HydPy. The first concrete realisation is the GARTO submodel, which can be added to HydPy-L (and, in the future, to other main models as well) to simulate the effects of infiltration excess on runoff generation. This realisation of the submodel concept works, but we still need to work out many details to improve its usability. However, before doing so, we prefer to start another realisation to gain more experience on possible use cases.
The second possible use case is a potential evapotranspiration interface. So far, our only effort to factor out evapotranspiration was to implement evap_v001(which we now name
evap_fao
).evap_fao
calculates the FAO grass reference evapotranspiration, and main models like lland_v2 and wland_v001 can take this data as input. However,evap_fao
is not really a submodel but is implemented as a stand-alone model which must be connected to other models via the input/output node mechanism. This mechanism (currently) limits us to the exchange of scalar potential evapotranspiration values and requires more configuration effort than desired.The reason for selecting potential evapotranspiration (pet) as the second use case is that we currently try to extract the Turc-Wendling equation implemented in lland_v1 into the new model
evap_tw
(orevap_turcwendling
?) and the “norm-temperature” approach implemented in all application models of base model hland into the new modelevap_hbv
(or something likeevap_normed
orevap_climate
?). However, we cannot do so based on the input/output node mechanism. Both approaches do not calculate one scalar pet value per subbasin but individual values for different hydrological response units. We consider this an important feature when working with large subbasins, especially in mountainous regions with steep gradients of temperature and other meteorological factors. (Accordingly,evap_fao
currently would not be a good choice in such situations.)So, this opens the question if we should turn
evap_fao
into a submodel and designevap_tw
andevap_hvb
right from the start as submodels. If we decide so, this would likely mean we eliminate the input/output node mechanism sooner or later, which is still marked as an experimental feature in the documentation. The submodel concept has the potential to become superior in most (or all?) regards, and handling two modularisation strategies in parallel seems like an unnecessary effort. Going this way, we would also need to turn all meteo models into submodels.What would we need to do?
evap_fao
as a stand-alone model. This is not required for usual HydPy projects (where we model the complete water balance of river catchments) but would help if we want to calculate pet time series for other purposes.To clarify the "who reads the input data" issue: Most evaporation methods require air temperature input. Snow-related methods do so as well. hland_v1, for example, currently adjusts the average basin temperature to the elevation of individual zones. If we still let
hland_v1
do the job, it must do so only once for at least two purposes. Additionally, the evaporation and the snow module would receive consistent temperature estimates. These points speak for letting the main model preprocess the input time series. However, I tend to favour letting the submodels read and process the input data in this case, as it allows for more flexibility. More importantly, this would keep the input data requirements of the involved models transparent. Consider, for example, air pressure, which is required by very few evaporation methods (e.g.evap_fao
). Ifhland_v1
were to supply all input data to the evaporation submodel andevap_fao
, it would have to specify air pressure as required but actually use it only under specific configurations. (Regarding consistency: we could also factor out the height adjustment of air temperature so that users could use it as a sub-submodel and be free to select the same approach for different purposes. However, we have not decided if we will support that submodels can reference other submodels. So far, it is not forbidden.)